Merge "[PackageInstallerService] only update session badge when needed"
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/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/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index 7345453..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;
@@ -42,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;
 
@@ -116,13 +118,14 @@
     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);
@@ -141,10 +144,16 @@
             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 {
@@ -236,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();
@@ -867,4 +876,10 @@
     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/rubidium/Android.bp b/apct-tests/perftests/rubidium/Android.bp
index 1f764d6..ba2b442 100644
--- a/apct-tests/perftests/rubidium/Android.bp
+++ b/apct-tests/perftests/rubidium/Android.bp
@@ -29,10 +29,11 @@
         "androidx.test.rules",
         "androidx.annotation_annotation",
         "apct-perftests-utils",
-        "collector-device-lib",
+        "collector-device-lib-platform",
         "compatibility-device-util-axt",
         "platform-test-annotations",
         "adservices-service-core",
+        "androidx.core_core",
     ],
     test_suites: ["device-tests"],
     data: [":perfetto_artifacts"],
diff --git a/apct-tests/perftests/rubidium/assets/generate_bid.wasm b/apct-tests/perftests/rubidium/assets/generate_bid.wasm
new file mode 100644
index 0000000..5e7fe9e
--- /dev/null
+++ b/apct-tests/perftests/rubidium/assets/generate_bid.wasm
Binary files differ
diff --git a/apct-tests/perftests/rubidium/assets/generate_bid_using_wasm.js b/apct-tests/perftests/rubidium/assets/generate_bid_using_wasm.js
new file mode 100644
index 0000000..bc50d0a
--- /dev/null
+++ b/apct-tests/perftests/rubidium/assets/generate_bid_using_wasm.js
@@ -0,0 +1,24 @@
+function generateBid(ad, wasmModule) {
+  let input = ad.metadata.input;
+
+  const instance = new WebAssembly.Instance(wasmModule);
+
+  const memory = instance.exports.memory;
+  const input_in_memory = new Float32Array(memory.buffer, 0, 200);
+  for (let i = 0; i < input.length; ++i) {
+    input_in_memory[i] = input[i];
+  }
+  const results = [
+    instance.exports.nn_forward_model0(input_in_memory.length, input_in_memory),
+    instance.exports.nn_forward_model1(input_in_memory.length, input_in_memory),
+    instance.exports.nn_forward_model2(input_in_memory.length, input_in_memory),
+    instance.exports.nn_forward_model3(input_in_memory.length, input_in_memory),
+    instance.exports.nn_forward_model4(input_in_memory.length, input_in_memory),
+  ];
+  const bid = results.map(x => Math.max(x, 1)).reduce((x, y) => x * y);
+  return {
+    ad: 'example',
+    bid: bid,
+    render: ad.renderUrl
+  }
+}
\ No newline at end of file
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..81685cb 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,82 @@
 
 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 static org.junit.Assume.assumeTrue;
+
+import android.annotation.SuppressLint;
 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.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.Random;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
 
-@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 String TAG = JSScriptEngine.TAG;
+    private static final Context sContext = ApplicationProvider.getApplicationContext();
+    private static final ExecutorService sExecutorService = Executors.newFixedThreadPool(10);
+
+    private static final JSScriptEngine sJSScriptEngine =
+            JSScriptEngine.getInstanceForTesting(
+                    sContext, Profiler.createInstance(JSScriptEngine.TAG));
 
     @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
 
+    @Before
+    public void before() throws Exception {
+        // 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 +121,7 @@
 
         state.resumeTiming();
         while (state.keepRunning()) {
-            callJSEngine(
-                    jsTestFile, ImmutableList.of(adDataArgument), "generateBid");
+            callJSEngine(jsTestFile, ImmutableList.of(adDataArgument), "generateBid");
         }
     }
 
@@ -99,8 +131,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 +141,136 @@
         }
     }
 
+    @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);
+    }
+
+    @SuppressLint("DefaultLocale")
+    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));
+    }
+
+    @Test
+    public void evaluate_turtledoveWasm() throws Exception {
+        assumeTrue(sJSScriptEngine.isWasmSupported().get(3, TimeUnit.SECONDS));
+
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        state.pauseTiming();
+
+        String jsTestFile = readAsset("generate_bid_using_wasm.js");
+        byte[] wasmTestFile = readBinaryAsset("generate_bid.wasm");
+        JSScriptArgument[] inputBytes = new JSScriptArgument[200];
+        Random rand = new Random();
+        for (int i = 0; i < inputBytes.length; i++) {
+            byte value = (byte) (rand.nextInt(2 * Byte.MAX_VALUE) - Byte.MIN_VALUE);
+            inputBytes[i] = JSScriptArgument.numericArg("_", value);
+        }
+        JSScriptArgument adDataArgument =
+                recordArg(
+                        "ad",
+                        stringArg("render_url", "http://google.com"),
+                        recordArg("metadata", JSScriptArgument.arrayArg("input", inputBytes)));
+
+        state.resumeTiming();
+        while (state.keepRunning()) {
+            callJSEngine(jsTestFile, wasmTestFile, ImmutableList.of(adDataArgument), "generateBid");
+        }
+    }
+
     private 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(
+            @NonNull String jsScript,
+            @NonNull byte[] wasmScript,
+            @NonNull List<JSScriptArgument> args,
+            @NonNull String functionName)
+            throws Exception {
+        return callJSEngine(sJSScriptEngine, jsScript, wasmScript, args, functionName);
+    }
+
+    private static String callJSEngine(
             @NonNull JSScriptEngine jsScriptEngine,
             @NonNull String jsScript,
             @NonNull List<JSScriptArgument> args,
@@ -131,15 +283,30 @@
         return futureResult.get();
     }
 
-    private ListenableFuture<String> callJSEngineAsync(
+    private String callJSEngine(
+            @NonNull JSScriptEngine jsScriptEngine,
+            @NonNull String jsScript,
+            @NonNull byte[] wasmScript,
+            @NonNull List<JSScriptArgument> args,
+            @NonNull String functionName)
+            throws Exception {
+        CountDownLatch resultLatch = new CountDownLatch(1);
+        ListenableFuture<String> futureResult =
+                callJSEngineAsync(
+                        jsScriptEngine, jsScript, wasmScript, args, functionName, resultLatch);
+        resultLatch.await();
+        return futureResult.get();
+    }
+
+    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 +315,29 @@
         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;
     }
+
+    private ListenableFuture<String> callJSEngineAsync(
+            @NonNull JSScriptEngine engine,
+            @NonNull String jsScript,
+            @NonNull byte[] wasmScript,
+            @NonNull List<JSScriptArgument> args,
+            @NonNull String functionName,
+            @NonNull CountDownLatch resultLatch) {
+        Objects.requireNonNull(engine);
+        Objects.requireNonNull(resultLatch);
+        ListenableFuture<String> result = engine.evaluate(jsScript, wasmScript, args, functionName);
+        result.addListener(resultLatch::countDown, sExecutorService);
+        return result;
+    }
+
+    private byte[] readBinaryAsset(@NonNull String assetName) throws IOException {
+        return sContext.getAssets().open(assetName).readAllBytes();
+    }
+
+    private String readAsset(@NonNull String assetName) throws IOException {
+        return new String(readBinaryAsset(assetName), StandardCharsets.UTF_8);
+    }
 }
diff --git a/apct-tests/perftests/surfaceflinger/Android.bp b/apct-tests/perftests/surfaceflinger/Android.bp
new file mode 100644
index 0000000..0c28bce
--- /dev/null
+++ b/apct-tests/perftests/surfaceflinger/Android.bp
@@ -0,0 +1,40 @@
+// 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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test {
+    name: "SurfaceFlingerPerfTests",
+    srcs: ["src/**/*.java"],
+    libs: ["android.test.runner.stubs"],
+    static_libs: [
+        "androidx.test.rules",
+        "androidx.test.ext.junit",
+        "androidx.annotation_annotation",
+        "apct-perftests-utils",
+        "collector-device-lib",
+        "platform-test-annotations",
+    ],
+    test_suites: ["device-tests"],
+    data: [":perfetto_artifacts"],
+    platform_apis: true,
+    certificate: "platform",
+}
diff --git a/apct-tests/perftests/surfaceflinger/AndroidManifest.xml b/apct-tests/perftests/surfaceflinger/AndroidManifest.xml
new file mode 100644
index 0000000..89a5219
--- /dev/null
+++ b/apct-tests/perftests/surfaceflinger/AndroidManifest.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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.perftests.surfaceflinger">
+
+    <application android:label="SurfaceFlingerPerfTests">
+        <uses-library android:name="android.test.runner" />
+        <activity android:name="android.perftests.utils.SurfaceFlingerTestActivity"
+                  android:exported="true">
+
+            <intent-filter>
+                <action android:name="com.android.perftests.core.PERFTEST" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.perftests.surfaceflinger">
+    </instrumentation>
+</manifest>
diff --git a/apct-tests/perftests/surfaceflinger/AndroidTest.xml b/apct-tests/perftests/surfaceflinger/AndroidTest.xml
new file mode 100644
index 0000000..b8bd8b4
--- /dev/null
+++ b/apct-tests/perftests/surfaceflinger/AndroidTest.xml
@@ -0,0 +1,63 @@
+<?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.
+-->
+<configuration description="Runs SurfaceFlingerPerfTests metric instrumentation.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-metric-instrumentation" />
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="install-arg" value="-t" />
+        <option name="test-file-name" value="SurfaceFlingerPerfTests.apk" />
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+        <option name="force-skip-system-props" value="true" />
+        <option name="run-command" value="input keyevent KEYCODE_WAKEUP" />
+        <option name="run-command" value="cmd window dismiss-keyguard" />
+        <option name="run-command" value="cmd package compile -m speed android.perftests.surfaceflinger" />
+    </target_preparer>
+
+    <!-- Needed for pushing the trace config file -->
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="push-file" key="trace_config_detailed.textproto" value="/data/misc/perfetto-traces/trace_config.textproto" />
+    </target_preparer>
+
+    <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
+    <option name="isolated-storage" value="false" />
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="package" value="android.perftests.surfaceflinger" />
+        <option name="hidden-api-checks" value="false"/>
+
+        <!-- Listener related args for collecting the traces and waiting for the device to stabilize. -->
+        <option name="device-listeners" value="android.device.collectors.PerfettoListener,android.device.collectors.SimpleperfListener" />
+
+        <!-- Guarantee that user defined RunListeners will be running before any of the default listeners defined in this runner. -->
+        <option name="instrumentation-arg" key="newRunListenerMode" value="true" />
+
+        <!-- PerfettoListener related arguments -->
+        <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true" />
+        <option name="instrumentation-arg" key="perfetto_config_file" value="trace_config.textproto" />
+    </test>
+
+    <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+        <option name="directory-keys" value="/data/local/tmp/SurfaceFlingerPerfTests" />
+        <!-- Needed for pulling the collected trace config on to the host -->
+        <option name="pull-pattern-keys" value="perfetto_file_path" />
+    </metrics_collector>
+
+</configuration>
diff --git a/apct-tests/perftests/surfaceflinger/OWNERS b/apct-tests/perftests/surfaceflinger/OWNERS
new file mode 100644
index 0000000..0862c05
--- /dev/null
+++ b/apct-tests/perftests/surfaceflinger/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/apct-tests/perftests/surfaceflinger/README.md b/apct-tests/perftests/surfaceflinger/README.md
new file mode 100644
index 0000000..0dec70f
--- /dev/null
+++ b/apct-tests/perftests/surfaceflinger/README.md
@@ -0,0 +1,34 @@
+## SurfaceFlinger performance tests
+
+### Precondition
+To reduce the variance of the test, if `perf-setup.sh` (platform_testing/scripts/perf-setup)
+is available, it is better to use the following instructions to lock CPU and GPU frequencies.
+```
+m perf-setup
+PERF_SETUP_PATH=/data/local/tmp/perf-setup.sh
+adb push $OUT/$PERF_SETUP_PATH $PERF_SETUP_PATH
+adb shell chmod +x $PERF_SETUP_PATH
+adb shell $PERF_SETUP_PATH
+```
+
+### Example to run
+Use `atest`
+```
+atest SurfaceFlingerPerfTests:SurfaceFlingerPerfTest -- \
+      --module-arg SurfaceFlingerPerfTests:instrumentation-arg:kill-bg:=true
+```
+Use `am instrument`
+```
+adb shell am instrument -w -r -e class android.surfaceflinger.SurfaceFlingerPerfTest \
+          -e kill-bg true \
+          com.android.perftests.surfaceflinger/androidx.test.runner.AndroidJUnitRunner
+```
+* `kill-bg` is optional.
+
+Test arguments
+- kill-bg
+    * boolean: Kill background process before running test.
+- profiling-iterations
+    * int: Run the extra iterations with enabling method profiling.
+- profiling-sampling
+    * int: The interval (0=trace each method, default is 10) of sample profiling in microseconds.
diff --git a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java
new file mode 100644
index 0000000..347cb78
--- /dev/null
+++ b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.surfaceflinger;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.perftests.utils.SurfaceFlingerTestActivity;
+
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.junit.runner.RunWith;
+
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class SurfaceFlingerPerfTest {
+    protected ActivityScenarioRule<SurfaceFlingerTestActivity> mActivityRule =
+            new ActivityScenarioRule<>(SurfaceFlingerTestActivity.class);
+    protected PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Rule
+    public final RuleChain mAllRules = RuleChain
+            .outerRule(mPerfStatusReporter)
+            .around(mActivityRule);
+
+    @Test
+    public void helloWorld() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            // Do Something
+        }
+
+    }
+}
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/SurfaceFlingerTestActivity.java b/apct-tests/perftests/utils/src/android/perftests/utils/SurfaceFlingerTestActivity.java
new file mode 100644
index 0000000..511ebbe
--- /dev/null
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/SurfaceFlingerTestActivity.java
@@ -0,0 +1,44 @@
+/*
+ * 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.perftests.utils;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.SurfaceView;
+import android.view.WindowManager;
+import android.widget.LinearLayout;
+
+/**
+ * A simple activity used for testing, e.g. performance of activity switching, or as a base
+ * container of testing view.
+ */
+public class SurfaceFlingerTestActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+
+        final LinearLayout layout = new LinearLayout(this);
+        layout.setOrientation(LinearLayout.VERTICAL);
+
+        final SurfaceView surfaceview = new SurfaceView(this);
+        layout.addView(surfaceview);
+        setContentView(layout);
+
+    }
+}
diff --git a/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl b/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl
index 9d11ca4..25caf4b 100644
--- a/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl
+++ b/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl
@@ -40,7 +40,6 @@
     long getNextWakeFromIdleTime();
     @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     AlarmManager.AlarmClockInfo getNextAlarmClock(int userId);
-    long currentNetworkTimeMillis();
     boolean canScheduleExactAlarms(String packageName);
     boolean hasScheduleExactAlarm(String packageName, int userId);
     int getConfigVersion();
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 7178a2bf..57b6935 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -90,7 +90,6 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
-import android.os.ParcelableException;
 import android.os.PowerExemptionManager;
 import android.os.PowerManager;
 import android.os.Process;
@@ -116,7 +115,6 @@
 import android.util.IndentingPrintWriter;
 import android.util.Log;
 import android.util.LongArrayQueue;
-import android.util.NtpTrustedTime;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -161,7 +159,6 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
-import java.time.DateTimeException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
@@ -335,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 =
@@ -670,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";
 
@@ -722,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;
 
         /**
@@ -769,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;
@@ -973,14 +971,6 @@
                         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,
@@ -1091,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,
@@ -1237,9 +1218,6 @@
             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();
 
@@ -1875,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);
@@ -2871,7 +2848,11 @@
                 } else {
                     needsPermission = false;
                     lowerQuota = allowWhileIdle;
-                    idleOptions = allowWhileIdle ? mOptsWithFgs.toBundle() : null;
+                    idleOptions = (allowWhileIdle || (alarmClock != null))
+                            // This avoids exceptions on existing alarms when the app upgrades to
+                            // target S. Note that FGS from pre-S apps isn't restricted anyway.
+                            ? mOptsWithFgs.toBundle()
+                            : null;
                     if (exact) {
                         exactAllowReason = EXACT_ALLOW_REASON_COMPAT;
                     }
@@ -3002,17 +2983,6 @@
         }
 
         @Override
-        public long currentNetworkTimeMillis() {
-            final NtpTrustedTime time = NtpTrustedTime.getInstance(getContext());
-            NtpTrustedTime.TimeResult ntpResult = time.getCachedTimeResult();
-            if (ntpResult != null) {
-                return ntpResult.currentTimeMillis();
-            } else {
-                throw new ParcelableException(new DateTimeException("Missing NTP fix"));
-            }
-        }
-
-        @Override
         public int getConfigVersion() {
             getContext().enforceCallingOrSelfPermission(Manifest.permission.DUMP,
                     "getConfigVersion");
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/JobConcurrencyManager.java b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
index 28116a8..5860384 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -543,6 +543,30 @@
     }
 
     /**
+     * Return {@code true} if the specified job has been executing for longer than the minimum
+     * execution guarantee.
+     */
+    @GuardedBy("mLock")
+    boolean isJobLongRunningLocked(@NonNull JobStatus job) {
+        if (!mRunningJobs.contains(job)) {
+            return false;
+        }
+
+        for (int i = mActiveServices.size() - 1; i >= 0; --i) {
+            final JobServiceContext jsc = mActiveServices.get(i);
+            final JobStatus jobStatus = jsc.getRunningJobLocked();
+
+            if (jobStatus == job) {
+                return !jsc.isWithinExecutionGuaranteeTime();
+            }
+        }
+
+        Slog.wtf(TAG, "Couldn't find long running job on a context");
+        mRunningJobs.remove(job);
+        return false;
+    }
+
+    /**
      * Returns true if a job that is "similar" to the provided job is currently running.
      * "Similar" in this context means any job that the {@link JobStore} would consider equivalent
      * and replace one with the other.
@@ -989,6 +1013,26 @@
         }
     }
 
+    /**
+     * Stops any jobs that have run for more than their minimum execution guarantee and are
+     * restricted by the given {@link JobRestriction}.
+     */
+    @GuardedBy("mLock")
+    void maybeStopLongRunningJobsLocked(@NonNull JobRestriction restriction) {
+        for (int i = mActiveServices.size() - 1; i >= 0; --i) {
+            final JobServiceContext jsc = mActiveServices.get(i);
+            final JobStatus jobStatus = jsc.getRunningJobLocked();
+
+            if (jobStatus != null && !jsc.isWithinExecutionGuaranteeTime()
+                    && restriction.isJobRestricted(jobStatus)) {
+                jsc.cancelExecutingJobLocked(restriction.getReason(),
+                        restriction.getInternalReason(),
+                        JobParameters.getInternalReasonCodeDescription(
+                                restriction.getInternalReason()));
+            }
+        }
+    }
+
     @GuardedBy("mLock")
     void stopNonReadyActiveJobsLocked() {
         for (int i = 0; i < mActiveServices.size(); i++) {
@@ -1349,6 +1393,12 @@
         if (mPowerManager.isDeviceIdleMode()) {
             return "deep doze";
         }
+        final JobRestriction jobRestriction;
+        if ((jobRestriction = mService.checkIfRestricted(js)) != null) {
+            return "restriction:"
+                    + JobParameters.getInternalReasonCodeDescription(
+                            jobRestriction.getInternalReason());
+        }
 
         // Update config in case memory usage has changed significantly.
         updateCounterConfigLocked();
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 60afdc7..f16d8cf1 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -1772,6 +1772,12 @@
         return mConcurrencyManager.isJobRunningLocked(job);
     }
 
+    /** @see JobConcurrencyManager#isJobLongRunningLocked(JobStatus) */
+    @GuardedBy("mLock")
+    public boolean isLongRunningLocked(JobStatus job) {
+        return mConcurrencyManager.isJobLongRunningLocked(job);
+    }
+
     private void noteJobPending(JobStatus job) {
         mJobPackageTracker.notePending(job);
     }
@@ -2050,6 +2056,17 @@
     }
 
     @Override
+    public void onRestrictionStateChanged(@NonNull JobRestriction restriction,
+            boolean stopLongRunningJobs) {
+        mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
+        if (stopLongRunningJobs) {
+            synchronized (mLock) {
+                mConcurrencyManager.maybeStopLongRunningJobsLocked(restriction);
+            }
+        }
+    }
+
+    @Override
     public void onRunJobNow(JobStatus jobStatus) {
         if (jobStatus == null) {
             mHandler.obtainMessage(MSG_CHECK_JOB_GREEDY).sendToTarget();
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..72553ed 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;
@@ -734,10 +736,10 @@
     @GuardedBy("mLock")
     private void doCancelLocked(@JobParameters.StopReason int stopReasonCode,
             int internalStopReasonCode, @Nullable String debugReason) {
-        if (mVerb == VERB_FINISHED) {
+        if (mVerb == VERB_FINISHED || mVerb == VERB_STOPPING) {
             if (DEBUG) {
                 Slog.d(TAG,
-                        "Trying to process cancel for torn-down context, ignoring.");
+                        "Too late to process cancel for context (verb=" + mVerb + "), ignoring.");
             }
             return;
         }
diff --git a/apex/jobscheduler/service/java/com/android/server/job/StateChangedListener.java b/apex/jobscheduler/service/java/com/android/server/job/StateChangedListener.java
index 1068bda..d7bd030 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/StateChangedListener.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/StateChangedListener.java
@@ -21,6 +21,7 @@
 import android.util.ArraySet;
 
 import com.android.server.job.controllers.JobStatus;
+import com.android.server.job.restrictions.JobRestriction;
 
 import java.util.List;
 
@@ -37,6 +38,16 @@
     void onControllerStateChanged(@Nullable ArraySet<JobStatus> changedJobs);
 
     /**
+     * Called by a {@link com.android.server.job.restrictions.JobRestriction} to notify the
+     * JobScheduler that it should check on the state of all jobs.
+     *
+     * @param stopLongRunningJobs Whether to stop any jobs that have run for more than their minimum
+     *                            execution guarantee and are restricted by the changed restriction
+     */
+    void onRestrictionStateChanged(@NonNull JobRestriction restriction,
+            boolean stopLongRunningJobs);
+
+    /**
      * Called by the controller to notify the JobManager that regardless of the state of the task,
      * it must be run immediately.
      * @param jobStatus The state of the task which is to be run immediately. <strong>null
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java
index 63781ae..5ef6855 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java
@@ -34,6 +34,7 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.JobSchedulerBackgroundThread;
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
@@ -100,6 +101,10 @@
     @Override
     @GuardedBy("mLock")
     public void prepareForExecutionLocked(JobStatus jobStatus) {
+        if (!jobStatus.hasPowerConstraint()) {
+            // Ignore all jobs the controller wouldn't be tracking.
+            return;
+        }
         if (DEBUG) {
             Slog.d(TAG, "Prepping for " + jobStatus.toShortString());
         }
@@ -259,6 +264,16 @@
         }
     }
 
+    @VisibleForTesting
+    ArraySet<JobStatus> getTrackedJobs() {
+        return mTrackedTasks;
+    }
+
+    @VisibleForTesting
+    ArraySet<JobStatus> getTopStartedJobs() {
+        return mTopStartedJobs;
+    }
+
     @Override
     public void dumpControllerStateLocked(IndentingPrintWriter pw,
             Predicate<JobStatus> predicate) {
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/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java b/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java
index 40244e8..a007a69 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java
@@ -73,9 +73,10 @@
                                 // bucket (thus resulting in us beginning to enforce the tightest
                                 // restrictions).
                                 || (mThermalStatus < UPPER_THRESHOLD && status > UPPER_THRESHOLD);
+                final boolean increased = mThermalStatus < status;
                 mThermalStatus = status;
                 if (significantChange) {
-                    mService.onControllerStateChanged(null);
+                    mService.onRestrictionStateChanged(ThermalStatusRestriction.this, increased);
                 }
             }
         });
@@ -89,16 +90,19 @@
         final int priority = job.getEffectivePriority();
         if (mThermalStatus >= HIGHER_PRIORITY_THRESHOLD) {
             // For moderate throttling, only let expedited jobs and high priority regular jobs that
-            // are already running run.
+            // haven't been running for long run.
             return !job.shouldTreatAsExpeditedJob()
                     && !(priority == JobInfo.PRIORITY_HIGH
-                    && mService.isCurrentlyRunningLocked(job));
+                        && mService.isCurrentlyRunningLocked(job)
+                        && !mService.isLongRunningLocked(job));
         }
         if (mThermalStatus >= LOW_PRIORITY_THRESHOLD) {
             // For light throttling, throttle all min priority jobs and all low priority jobs that
-            // aren't already running.
-            return (priority == JobInfo.PRIORITY_LOW && !mService.isCurrentlyRunningLocked(job))
-                    || priority == JobInfo.PRIORITY_MIN;
+            // aren't already running or have been running for long enough.
+            return priority == JobInfo.PRIORITY_MIN
+                    || (priority == JobInfo.PRIORITY_LOW
+                        && (!mService.isCurrentlyRunningLocked(job)
+                            || mService.isLongRunningLocked(job)));
         }
         return false;
     }
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index fbb99d2..836801d 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -47,10 +47,16 @@
 #define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000)  // 1 Day
 
 // Skip these sections (for dumpstate only)
-// Skip logs (1100 - 1108) and traces (1200 - 1202) because they are already in the bug report.
+// Skip logs (1100 - 1108), traces (1200 - 1202), dumpsys (3000 - 3024, 3027 - 3056, 4000 - 4001)
+// because they are already in the bug report.
 #define SKIPPED_DUMPSTATE_SECTIONS { \
             1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, /* Logs */ \
-            1200, 1201, 1202, /* Native, hal, java traces */ }
+            1200, 1201, 1202, /* Native, hal, java traces */ \
+            3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013, \
+            3014, 3015, 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023, 3024, 3027, 3028, 3029, \
+            3030, 3031, 3032, 3033, 3034, 3035, 3036, 3037, 3038, 3039, 3040, 3041, 3042, 3043, \
+            3044, 3045, 3046, 3047, 3048, 3049, 3050, 3051, 3052, 3053, 3054, 3055, 3056, 4000, \
+            4001, /* Dumpsys */ }
 
 namespace android {
 namespace os {
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 5e6d32d..7fbf3ec 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();
@@ -31610,7 +31613,7 @@
 
   public interface OutcomeReceiver<R, E extends java.lang.Throwable> {
     method public default void onError(@NonNull E);
-    method public void onResult(@NonNull R);
+    method public void onResult(R);
   }
 
   public final class Parcel {
@@ -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..463d0c49 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);
@@ -3325,7 +3326,7 @@
     method @NonNull public java.util.concurrent.Executor getExecutor();
     method @NonNull public android.window.TaskFragmentOrganizerToken getOrganizerToken();
     method public void onTaskFragmentAppeared(@NonNull android.window.TaskFragmentInfo);
-    method public void onTaskFragmentError(@NonNull android.os.IBinder, @NonNull Throwable);
+    method public void onTaskFragmentError(@NonNull android.os.IBinder, @Nullable android.window.TaskFragmentInfo, int, @NonNull Throwable);
     method public void onTaskFragmentInfoChanged(@NonNull android.window.TaskFragmentInfo);
     method public void onTaskFragmentParentInfoChanged(@NonNull android.os.IBinder, @NonNull android.content.res.Configuration);
     method public void onTaskFragmentVanished(@NonNull android.window.TaskFragmentInfo);
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 a3a3615..c2c065b 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -16,11 +16,8 @@
 
 package android.accounts;
 
-import android.Manifest;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -152,6 +149,7 @@
     }
 
     private class Transport extends IAccountAuthenticator.Stub {
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
         @Override
         public void addAccount(IAccountAuthenticatorResponse response, String accountType,
                 String authTokenType, String[] features, Bundle options)
@@ -161,7 +159,6 @@
                         + ", authTokenType " + authTokenType
                         + ", features " + (features == null ? "[]" : Arrays.toString(features)));
             }
-            checkBinderPermission();
             try {
                 final Bundle result = AbstractAccountAuthenticator.this.addAccount(
                     new AccountAuthenticatorResponse(response),
@@ -183,13 +180,13 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
         @Override
         public void confirmCredentials(IAccountAuthenticatorResponse response,
                 Account account, Bundle options) throws RemoteException {
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "confirmCredentials: " + account);
             }
-            checkBinderPermission();
             try {
                 final Bundle result = AbstractAccountAuthenticator.this.confirmCredentials(
                     new AccountAuthenticatorResponse(response), account, options);
@@ -208,6 +205,7 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
         @Override
         public void getAuthTokenLabel(IAccountAuthenticatorResponse response,
                 String authTokenType)
@@ -215,7 +213,6 @@
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "getAuthTokenLabel: authTokenType " + authTokenType);
             }
-            checkBinderPermission();
             try {
                 Bundle result = new Bundle();
                 result.putString(AccountManager.KEY_AUTH_TOKEN_LABEL,
@@ -233,6 +230,7 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
         @Override
         public void getAuthToken(IAccountAuthenticatorResponse response,
                 Account account, String authTokenType, Bundle loginOptions)
@@ -241,7 +239,6 @@
                 Log.v(TAG, "getAuthToken: " + account
                         + ", authTokenType " + authTokenType);
             }
-            checkBinderPermission();
             try {
                 final Bundle result = AbstractAccountAuthenticator.this.getAuthToken(
                         new AccountAuthenticatorResponse(response), account,
@@ -261,6 +258,7 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
         @Override
         public void updateCredentials(IAccountAuthenticatorResponse response, Account account,
                 String authTokenType, Bundle loginOptions) throws RemoteException {
@@ -268,7 +266,6 @@
                 Log.v(TAG, "updateCredentials: " + account
                         + ", authTokenType " + authTokenType);
             }
-            checkBinderPermission();
             try {
                 final Bundle result = AbstractAccountAuthenticator.this.updateCredentials(
                     new AccountAuthenticatorResponse(response), account,
@@ -290,10 +287,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 +302,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 +317,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 +332,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 +348,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(
@@ -369,6 +366,7 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
         @Override
         public void startAddAccountSession(IAccountAuthenticatorResponse response,
                 String accountType, String authTokenType, String[] features, Bundle options)
@@ -379,7 +377,6 @@
                         + ", authTokenType " + authTokenType
                         + ", features " + (features == null ? "[]" : Arrays.toString(features)));
             }
-            checkBinderPermission();
             try {
                 final Bundle result = AbstractAccountAuthenticator.this.startAddAccountSession(
                         new AccountAuthenticatorResponse(response), accountType, authTokenType,
@@ -399,6 +396,7 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
         @Override
         public void startUpdateCredentialsSession(
                 IAccountAuthenticatorResponse response,
@@ -411,7 +409,6 @@
                         + ", authTokenType "
                         + authTokenType);
             }
-            checkBinderPermission();
             try {
                 final Bundle result = AbstractAccountAuthenticator.this
                         .startUpdateCredentialsSession(
@@ -438,6 +435,7 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
         @Override
         public void finishSession(
                 IAccountAuthenticatorResponse response,
@@ -446,7 +444,6 @@
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "finishSession: accountType " + accountType);
             }
-            checkBinderPermission();
             try {
                 final Bundle result = AbstractAccountAuthenticator.this.finishSession(
                         new AccountAuthenticatorResponse(response), accountType, sessionBundle);
@@ -465,12 +462,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(
@@ -510,14 +507,6 @@
         }
     }
 
-    private void checkBinderPermission() {
-        final int uid = Binder.getCallingUid();
-        final String perm = Manifest.permission.ACCOUNT_MANAGER;
-        if (mContext.checkCallingOrSelfPermission(perm) != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException("caller uid " + uid + " lacks " + perm);
-        }
-    }
-
     private Transport mTransport = new Transport();
 
     /**
diff --git a/core/java/android/accounts/IAccountAuthenticator.aidl b/core/java/android/accounts/IAccountAuthenticator.aidl
index 701cecf..c74b9d0 100644
--- a/core/java/android/accounts/IAccountAuthenticator.aidl
+++ b/core/java/android/accounts/IAccountAuthenticator.aidl
@@ -28,6 +28,7 @@
     /**
      * prompts the user for account information and adds the result to the IAccountManager
      */
+    @EnforcePermission("ACCOUNT_MANAGER")
     @UnsupportedAppUsage
     void addAccount(in IAccountAuthenticatorResponse response, String accountType,
         String authTokenType, in String[] requiredFeatures, in Bundle options);
@@ -35,6 +36,7 @@
     /**
      * prompts the user for the credentials of the account
      */
+    @EnforcePermission("ACCOUNT_MANAGER")
     @UnsupportedAppUsage
     void confirmCredentials(in IAccountAuthenticatorResponse response, in Account account,
         in Bundle options);
@@ -42,6 +44,7 @@
     /**
      * gets the password by either prompting the user or querying the IAccountManager
      */
+    @EnforcePermission("ACCOUNT_MANAGER")
     @UnsupportedAppUsage
     void getAuthToken(in IAccountAuthenticatorResponse response, in Account account,
         String authTokenType, in Bundle options);
@@ -49,12 +52,14 @@
     /**
      * Gets the user-visible label of the given authtoken type.
      */
+    @EnforcePermission("ACCOUNT_MANAGER")
     @UnsupportedAppUsage
     void getAuthTokenLabel(in IAccountAuthenticatorResponse response, String authTokenType);
 
     /**
      * prompts the user for a new password and writes it to the IAccountManager
      */
+    @EnforcePermission("ACCOUNT_MANAGER")
     @UnsupportedAppUsage
     void updateCredentials(in IAccountAuthenticatorResponse response, in Account account,
         String authTokenType, in Bundle options);
@@ -62,6 +67,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 +75,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 +83,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 +98,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);
 
@@ -96,12 +106,14 @@
      * Starts the add account session by prompting the user for account information
      * and return a Bundle containing data to finish the session later.
      */
+    @EnforcePermission("ACCOUNT_MANAGER")
     void startAddAccountSession(in IAccountAuthenticatorResponse response, String accountType,
         String authTokenType, in String[] requiredFeatures, in Bundle options);
 
     /**
      * Prompts the user for a new password but does not write it to the IAccountManager.
      */
+    @EnforcePermission("ACCOUNT_MANAGER")
     void startUpdateCredentialsSession(in IAccountAuthenticatorResponse response, in Account account,
         String authTokenType, in Bundle options);
 
@@ -110,12 +122,14 @@
      * startUpdateCredentialsSession(...) by adding account to or updating local credentials
      * in the IAccountManager.
      */
+    @EnforcePermission("ACCOUNT_MANAGER")
     void finishSession(in IAccountAuthenticatorResponse response, String accountType,
         in Bundle sessionBundle);
 
     /**
      * 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 493cb87..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();
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 d9e09604..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;
     }
 
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 6092b30..9072b50 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -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/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/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/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/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index f98ad4e..6866510 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -379,8 +379,8 @@
      * Only one {@link ComponentName} in the entire system should be enabled, and the rest of the
      * components are not started by this intent.
      *
-     * @deprecated Starting from Android T, the system no longer launches an intent with this action
-     * when user provisioning completes.
+     * @deprecated Starting from Android 13, the system no longer launches an intent with this
+     * action when user provisioning completes.
      * @hide
      */
     @Deprecated
@@ -14626,7 +14626,8 @@
     /**
      * Called by a device owner or a profile owner to disable user control over apps. User will not
      * be able to clear app data or force-stop packages. When called by a device owner, applies to
-     * all users on the device.
+     * all users on the device. Starting from Android 13, packages with user control disabled are
+     * exempted from being put in the "restricted" App Standby Bucket.
      *
      * @param admin which {@link DeviceAdminReceiver} this request is associated with
      * @param packages The package names for the apps.
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/time/TimeCapabilities.java b/core/java/android/app/time/TimeCapabilities.java
index 9b9dce2b..44bc178 100644
--- a/core/java/android/app/time/TimeCapabilities.java
+++ b/core/java/android/app/time/TimeCapabilities.java
@@ -39,16 +39,15 @@
  */
 public final class TimeCapabilities implements Parcelable {
 
-    public static final @NonNull Creator<TimeCapabilities> CREATOR =
-            new Creator<TimeCapabilities>() {
-                public TimeCapabilities createFromParcel(Parcel in) {
-                    return TimeCapabilities.createFromParcel(in);
-                }
+    public static final @NonNull Creator<TimeCapabilities> CREATOR = new Creator<>() {
+        public TimeCapabilities createFromParcel(Parcel in) {
+            return TimeCapabilities.createFromParcel(in);
+        }
 
-                public TimeCapabilities[] newArray(int size) {
-                    return new TimeCapabilities[size];
-                }
-            };
+        public TimeCapabilities[] newArray(int size) {
+            return new TimeCapabilities[size];
+        }
+    };
 
 
     /**
diff --git a/core/java/android/app/timedetector/ITimeDetectorService.aidl b/core/java/android/app/timedetector/ITimeDetectorService.aidl
index fc7afb4..0eb2b54 100644
--- a/core/java/android/app/timedetector/ITimeDetectorService.aidl
+++ b/core/java/android/app/timedetector/ITimeDetectorService.aidl
@@ -20,10 +20,9 @@
 import android.app.time.ITimeDetectorListener;
 import android.app.time.TimeCapabilitiesAndConfig;
 import android.app.time.TimeConfiguration;
-import android.app.timedetector.GnssTimeSuggestion;
 import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timedetector.NetworkTimeSuggestion;
 import android.app.timedetector.TelephonyTimeSuggestion;
+import android.app.timedetector.TimePoint;
 
 /**
  * System private API to communicate with time detector service.
@@ -45,9 +44,9 @@
 
   boolean updateConfiguration(in TimeConfiguration timeConfiguration);
 
-  void suggestExternalTime( in ExternalTimeSuggestion timeSuggestion);
-  void suggestGnssTime(in GnssTimeSuggestion timeSuggestion);
+  void suggestExternalTime(in ExternalTimeSuggestion timeSuggestion);
   boolean suggestManualTime(in ManualTimeSuggestion timeSuggestion);
-  void suggestNetworkTime(in NetworkTimeSuggestion timeSuggestion);
   void suggestTelephonyTime(in TelephonyTimeSuggestion timeSuggestion);
+
+  TimePoint latestNetworkTime();
 }
diff --git a/core/java/android/app/timedetector/NetworkTimeSuggestion.aidl b/core/java/android/app/timedetector/NetworkTimeSuggestion.aidl
deleted file mode 100644
index 731c907..0000000
--- a/core/java/android/app/timedetector/NetworkTimeSuggestion.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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 android.app.timedetector;
-
-parcelable NetworkTimeSuggestion;
diff --git a/core/java/android/app/timedetector/NetworkTimeSuggestion.java b/core/java/android/app/timedetector/NetworkTimeSuggestion.java
deleted file mode 100644
index e93c75c..0000000
--- a/core/java/android/app/timedetector/NetworkTimeSuggestion.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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 android.app.timedetector;
-
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.ShellCommand;
-import android.os.TimestampedValue;
-
-import java.io.PrintWriter;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * A time signal from a network time source like NTP.
- *
- * <p>See {@link TimeSuggestionHelper} for property information.
- *
- * @hide
- */
-public final class NetworkTimeSuggestion implements Parcelable {
-
-    public static final @NonNull Creator<NetworkTimeSuggestion> CREATOR =
-            new Creator<NetworkTimeSuggestion>() {
-                public NetworkTimeSuggestion createFromParcel(Parcel in) {
-                    TimeSuggestionHelper helper = TimeSuggestionHelper.handleCreateFromParcel(
-                            NetworkTimeSuggestion.class, in);
-                    return new NetworkTimeSuggestion(helper);
-                }
-
-                public NetworkTimeSuggestion[] newArray(int size) {
-                    return new NetworkTimeSuggestion[size];
-                }
-            };
-
-    @NonNull private final TimeSuggestionHelper mTimeSuggestionHelper;
-
-    public NetworkTimeSuggestion(@NonNull TimestampedValue<Long> unixEpochTime) {
-        mTimeSuggestionHelper = new TimeSuggestionHelper(
-                NetworkTimeSuggestion.class, unixEpochTime);
-    }
-
-    private NetworkTimeSuggestion(@NonNull TimeSuggestionHelper helper) {
-        mTimeSuggestionHelper = Objects.requireNonNull(helper);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        mTimeSuggestionHelper.handleWriteToParcel(dest, flags);
-    }
-
-    @NonNull
-    public TimestampedValue<Long> getUnixEpochTime() {
-        return mTimeSuggestionHelper.getUnixEpochTime();
-    }
-
-    @NonNull
-    public List<String> getDebugInfo() {
-        return mTimeSuggestionHelper.getDebugInfo();
-    }
-
-    /**
-     * Associates information with the instance that can be useful for debugging / logging. The
-     * information is present in {@link #toString()} but is not considered for {@link
-     * #equals(Object)} and {@link #hashCode()}.
-     */
-    public void addDebugInfo(String... debugInfos) {
-        mTimeSuggestionHelper.addDebugInfo(debugInfos);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-        NetworkTimeSuggestion that = (NetworkTimeSuggestion) o;
-        return mTimeSuggestionHelper.handleEquals(that.mTimeSuggestionHelper);
-    }
-
-    @Override
-    public int hashCode() {
-        return mTimeSuggestionHelper.hashCode();
-    }
-
-    @Override
-    public String toString() {
-        return mTimeSuggestionHelper.handleToString();
-    }
-
-    /** @hide */
-    public static NetworkTimeSuggestion parseCommandLineArg(@NonNull ShellCommand cmd)
-            throws IllegalArgumentException {
-        return new NetworkTimeSuggestion(
-                TimeSuggestionHelper.handleParseCommandLineArg(NetworkTimeSuggestion.class, cmd));
-    }
-
-    /** @hide */
-    public static void printCommandLineOpts(PrintWriter pw) {
-        TimeSuggestionHelper.handlePrintCommandLineOpts(pw, "Network", NetworkTimeSuggestion.class);
-    }
-}
diff --git a/core/java/android/app/timedetector/TimeDetector.java b/core/java/android/app/timedetector/TimeDetector.java
index abfba3a..db1614b 100644
--- a/core/java/android/app/timedetector/TimeDetector.java
+++ b/core/java/android/app/timedetector/TimeDetector.java
@@ -24,7 +24,12 @@
 import android.os.TimestampedValue;
 
 /**
- * The interface through which system components can send signals to the TimeDetectorService.
+ * The interface through which system components can query and send signals to the
+ * TimeDetectorService.
+ *
+ * <p>SDK APIs are exposed on {@link android.app.time.TimeManager} to obscure the internal split
+ * between time and time zone detection services. Migrate APIs there if they need to be part of an
+ * SDK API.
  *
  * @hide
  */
@@ -111,20 +116,4 @@
      */
     @RequiresPermission(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE)
     boolean suggestManualTime(@NonNull ManualTimeSuggestion timeSuggestion);
-
-    /**
-     * Suggests the time according to a network time source like NTP.
-     *
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.SET_TIME)
-    void suggestNetworkTime(NetworkTimeSuggestion timeSuggestion);
-
-    /**
-     * Suggests the time according to a gnss time source.
-     *
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.SET_TIME)
-    void suggestGnssTime(GnssTimeSuggestion timeSuggestion);
 }
diff --git a/core/java/android/app/timedetector/TimeDetectorHelper.java b/core/java/android/app/timedetector/TimeDetectorHelper.java
new file mode 100644
index 0000000..04f72de
--- /dev/null
+++ b/core/java/android/app/timedetector/TimeDetectorHelper.java
@@ -0,0 +1,158 @@
+/*
+ * 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.app.timedetector;
+
+import android.annotation.NonNull;
+import android.os.Build;
+
+import java.time.Instant;
+
+/**
+ * A utility class for fundamental time detector-related logic that doesn't need to communicate with
+ * the time detector service, i.e. because it can use SDK APIs or hard-coded facts, and doesn't need
+ * permissions or singleton state. Putting logic here avoids the need to expose binder-based calls
+ * or to duplicate code to share related logic (since android.app.timedetector classes are visible
+ * to all processes).
+ *
+ * @hide
+ */
+// Not final for easy replacement / mocking during tests.
+public class TimeDetectorHelper {
+
+    /**
+     * See {@link #getManualDateSelectionYearMin()}. Chosen to produce Unix epoch times be greater
+     * than {@link #MANUAL_SUGGESTION_LOWER_BOUND}.
+     */
+    private static final int MANUAL_SUGGESTION_YEAR_MIN = 2015;
+
+    /**
+     * The maximum gregorian calendar year to allow for manual date selection on devices unlikely to
+     * have Y2038 issues. This serves as a sensible UI-enforced limit though the system server may
+     * support a larger upper bound. Users besides future archeologists are unlikely to need higher
+     * values, for a few years at least.
+     */
+    private static final int MANUAL_SUGGESTION_YEAR_MAX_WITHOUT_Y2038_ISSUE = 2100;
+
+    /**
+     * The maximum gregorian calendar year to allow for manual date selection on devices that may
+     * have Y2038 issues. This serves as a sensible UI-enforced limit though the system server may
+     * support a larger upper bound. That is, the signed 32-bit milliseconds value is
+     * 03:14:07 UTC on 19 January 2038, but this constant means users can only enter dates up to
+     * 2037-12-31. See {@link #MANUAL_SUGGESTION_YEAR_MAX_WITH_Y2038_ISSUE}.
+     *
+     * <p>Note: This UI limit also doesn't prevent devices reaching the Y2038 roll-over time through
+     * the natural passage of time, it just prevents users potentially causing issues in the years
+     * leading up to it accidentally via the UI.
+     */
+    private static final int MANUAL_SUGGESTION_YEAR_MAX_WITH_Y2038_ISSUE = 2037;
+
+    /**
+     * The upper bound for valid suggestions when the Y2038 issue is a risk. This is the instant
+     * when the Y2038 issue occurs.
+     */
+    private static final Instant SUGGESTION_UPPER_BOUND_WITH_Y2038_ISSUE =
+            Instant.ofEpochMilli(1000L * Integer.MAX_VALUE);
+
+    /**
+     * The upper bound for valid suggestions when the Y2038 issue is not a risk. This values means
+     * there is no practical upper bound.
+     *
+     * <p>Make sure this value remains in the value representable as a signed int64 Unix epoch
+     * millis value as in various places {@link Instant#toEpochMilli()} is called, and that throws
+     * an exception if the value is too large.
+     */
+    private static final Instant SUGGESTION_UPPER_BOUND_WIITHOUT_Y2038_ISSUE =
+            Instant.ofEpochMilli(Long.MAX_VALUE);
+
+    /** See {@link #getManualSuggestionLowerBound()}. */
+    private static final Instant MANUAL_SUGGESTION_LOWER_BOUND =
+            Instant.ofEpochMilli(1415491200000L); // Nov 5, 2014, 0:00 UTC
+
+    /**
+     * The lowest value in Unix epoch milliseconds that is considered a valid automatic suggestion.
+     * See also {@link #MANUAL_SUGGESTION_LOWER_BOUND}.
+     *
+     * <p>Note that this is a default value. The lower value enforced can be overridden to be
+     * lower in the system server with flags for testing.
+     */
+    private static final Instant AUTO_SUGGESTION_LOWER_BOUND_DEFAULT = Instant.ofEpochMilli(
+            Long.max(android.os.Environment.getRootDirectory().lastModified(), Build.TIME));
+
+    /** The singleton instance of this class. */
+    public static final TimeDetectorHelper INSTANCE = new TimeDetectorHelper();
+
+    /** Constructor present for subclassing in tests. Use {@link #INSTANCE} in production code. */
+    protected TimeDetectorHelper() {}
+
+    /**
+     * Returns the minimum gregorian calendar year to offer for manual date selection. This serves
+     * as a sensible UI-enforced lower limit, the system server may support a smaller lower bound.
+     */
+    public int getManualDateSelectionYearMin() {
+        return MANUAL_SUGGESTION_YEAR_MIN;
+    }
+
+    /**
+     * Returns the maximum gregorian calendar year to offer for manual date selection. This serves
+     * as a sensible UI-enforced lower limit, the system server may support a larger upper bound.
+     */
+    public int getManualDateSelectionYearMax() {
+        return getDeviceHasY2038Issue()
+                ? MANUAL_SUGGESTION_YEAR_MAX_WITH_Y2038_ISSUE
+                : MANUAL_SUGGESTION_YEAR_MAX_WITHOUT_Y2038_ISSUE;
+    }
+
+    /**
+     * Returns the lowest value in Unix epoch milliseconds that is considered a valid manual
+     * suggestion. For historical reasons Android has a different lower limit for manual input than
+     * automatic. This may change in the future to align with automatic suggestions, but has been
+     * kept initially to avoid breaking manual tests that are hard-coded with old dates real users
+     * will never want to use.
+     */
+    @NonNull
+    public Instant getManualSuggestionLowerBound() {
+        return MANUAL_SUGGESTION_LOWER_BOUND;
+    }
+
+    /**
+     * Returns the lowest value in Unix epoch milliseconds that is considered a valid automatic
+     * suggestion. See also {@link #MANUAL_SUGGESTION_LOWER_BOUND}.
+     *
+     * <p>Note that this is a default value. The lower value enforced can be overridden to be
+     * different in the system server with server flags.
+     */
+    @NonNull
+    public Instant getAutoSuggestionLowerBoundDefault() {
+        return AUTO_SUGGESTION_LOWER_BOUND_DEFAULT;
+    }
+
+    /** Returns the upper bound to enforce for all time suggestions (manual and automatic). */
+    @NonNull
+    public Instant getSuggestionUpperBound() {
+        return getDeviceHasY2038Issue()
+                ? SUGGESTION_UPPER_BOUND_WITH_Y2038_ISSUE
+                : SUGGESTION_UPPER_BOUND_WIITHOUT_Y2038_ISSUE;
+    }
+
+    /**
+     * Returns {@code true} if the device may be at risk of time_t overflow (because bionic
+     * defines time_t as a 32-bit signed integer for 32-bit processes).
+     */
+    private boolean getDeviceHasY2038Issue() {
+        return Build.SUPPORTED_32_BIT_ABIS.length > 0;
+    }
+}
diff --git a/core/java/android/app/timedetector/TimeDetectorImpl.java b/core/java/android/app/timedetector/TimeDetectorImpl.java
index b0aa3c8..54f8e3f 100644
--- a/core/java/android/app/timedetector/TimeDetectorImpl.java
+++ b/core/java/android/app/timedetector/TimeDetectorImpl.java
@@ -62,28 +62,4 @@
             throw e.rethrowFromSystemServer();
         }
     }
-
-    @Override
-    public void suggestNetworkTime(NetworkTimeSuggestion timeSuggestion) {
-        if (DEBUG) {
-            Log.d(TAG, "suggestNetworkTime called: " + timeSuggestion);
-        }
-        try {
-            mITimeDetectorService.suggestNetworkTime(timeSuggestion);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    @Override
-    public void suggestGnssTime(GnssTimeSuggestion timeSuggestion) {
-        if (DEBUG) {
-            Log.d(TAG, "suggestGnssTime called: " + timeSuggestion);
-        }
-        try {
-            mITimeDetectorService.suggestGnssTime(timeSuggestion);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
 }
diff --git a/core/java/android/app/timedetector/GnssTimeSuggestion.aidl b/core/java/android/app/timedetector/TimePoint.aidl
similarity index 79%
rename from core/java/android/app/timedetector/GnssTimeSuggestion.aidl
rename to core/java/android/app/timedetector/TimePoint.aidl
index 81475ec..80d4bc1 100644
--- a/core/java/android/app/timedetector/GnssTimeSuggestion.aidl
+++ b/core/java/android/app/timedetector/TimePoint.aidl
@@ -1,11 +1,11 @@
 /*
- * Copyright (C) 2020 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.
  * 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,
@@ -16,4 +16,4 @@
 
 package android.app.timedetector;
 
-parcelable GnssTimeSuggestion;
+parcelable TimePoint;
diff --git a/core/java/android/app/timedetector/TimePoint.java b/core/java/android/app/timedetector/TimePoint.java
new file mode 100644
index 0000000..aa079a9
--- /dev/null
+++ b/core/java/android/app/timedetector/TimePoint.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.app.timedetector;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Data class for passing a Unix epoch time anchored to the elapsed realtime clock.
+ *
+ * @hide
+ */
+public final class TimePoint implements Parcelable {
+
+    private final long mUnixEpochTimeMillis;
+    private final long mElapsedRealtimeMillis;
+
+    public TimePoint(long unixEpochTimeMillis, long elapsedRealtimeMillis) {
+        mUnixEpochTimeMillis = unixEpochTimeMillis;
+        mElapsedRealtimeMillis = elapsedRealtimeMillis;
+    }
+
+    /**
+     * The current Unix epoch time, according to the external source.
+     */
+    public long getUnixEpochTimeMillis() {
+        return mUnixEpochTimeMillis;
+    }
+
+    /**
+     * The elapsed millis since boot when {@link #getUnixEpochTimeMillis} was computed.
+     */
+    public long getElapsedRealtimeMillis() {
+        return mElapsedRealtimeMillis;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeLong(mUnixEpochTimeMillis);
+        out.writeLong(mElapsedRealtimeMillis);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof TimePoint)) {
+            return false;
+        }
+        TimePoint timePoint = (TimePoint) o;
+        return mUnixEpochTimeMillis == timePoint.mUnixEpochTimeMillis
+                && mElapsedRealtimeMillis == timePoint.mElapsedRealtimeMillis;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mUnixEpochTimeMillis, mElapsedRealtimeMillis);
+    }
+
+    @Override
+    public String toString() {
+        return "TimePoint{"
+                + "mUnixEpochTimeMillis=" + mUnixEpochTimeMillis
+                + ", mElapsedRealtimeMillis=" + mElapsedRealtimeMillis
+                + '}';
+    }
+
+    public static final @NonNull Creator<TimePoint> CREATOR =
+            new Creator<TimePoint>() {
+                public TimePoint createFromParcel(Parcel in) {
+                    long unixEpochTime = in.readLong();
+                    long elapsedRealtimeMillis = in.readLong();
+                    return new TimePoint(unixEpochTime, elapsedRealtimeMillis);
+                }
+
+                public TimePoint[] newArray(int size) {
+                    return new TimePoint[size];
+                }
+            };
+}
diff --git a/core/java/android/app/timedetector/TimeSuggestionHelper.java b/core/java/android/app/timedetector/TimeSuggestionHelper.java
index 9b99be6..e89839c 100644
--- a/core/java/android/app/timedetector/TimeSuggestionHelper.java
+++ b/core/java/android/app/timedetector/TimeSuggestionHelper.java
@@ -201,7 +201,8 @@
     public static void handlePrintCommandLineOpts(
             @NonNull PrintWriter pw, @NonNull String typeName, @NonNull Class<?> clazz) {
         pw.printf("%s suggestion options:\n", typeName);
-        pw.println("  --reference_time <elapsed realtime millis>");
+        pw.println("  --reference_time <elapsed realtime millis> - the elapsed realtime millis when"
+                + " unix epoch time was read");
         pw.println("  --unix_epoch_time <Unix epoch time millis>");
         pw.println();
         pw.println("See " + clazz.getName() + " for more information");
diff --git a/core/java/android/app/timezonedetector/TimeZoneDetector.java b/core/java/android/app/timezonedetector/TimeZoneDetector.java
index aac23d8..bae1c1c 100644
--- a/core/java/android/app/timezonedetector/TimeZoneDetector.java
+++ b/core/java/android/app/timezonedetector/TimeZoneDetector.java
@@ -22,7 +22,12 @@
 import android.content.Context;
 
 /**
- * The interface through which system components can send signals to the TimeZoneDetectorService.
+ * The interface through which system components can query and send signals to the
+ * TimeZoneDetectorService.
+ *
+ * <p>SDK APIs are exposed on {@link android.app.time.TimeManager} to obscure the internal split
+ * between time and time zone detection services. Migrate APIs there if they need to be part of an
+ * SDK API.
  *
  * @hide
  */
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/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/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/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..598170d 100644
--- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java
+++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java
@@ -26,6 +26,10 @@
 
 import java.lang.reflect.Array;
 import java.nio.ByteBuffer;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.LongBuffer;
 import java.util.ArrayList;
 
 /**
@@ -45,46 +49,49 @@
     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) {
+                          IntBuffer ib = buffer.asIntBuffer().get(int[].class.cast(arr), 0, size);
+                          // Update buffer position since the IntBuffer has independent position.
+                          buffer.position(buffer.position() + ib.position() * Integer.BYTES);
                       }
                 };
             } 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) {
+                          FloatBuffer fb =
+                                  buffer.asFloatBuffer().get(float[].class.cast(arr), 0, size);
+                          buffer.position(buffer.position() + fb.position() * Float.BYTES);
                       }
                 };
             } 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) {
+                          LongBuffer lb =
+                                  buffer.asLongBuffer().get(long[].class.cast(arr), 0, size);
+                          buffer.position(buffer.position() + lb.position() * Long.BYTES);
                       }
                 };
             } 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) {
+                          DoubleBuffer db =
+                                  buffer.asDoubleBuffer().get(double[].class.cast(arr), 0, size);
+                          buffer.position(buffer.position() + db.position() * Double.BYTES);
                       }
                 };
             } 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 +100,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 +150,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/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/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index c02f870..b108490 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.
@@ -2894,7 +2894,6 @@
         // Back callback is typically unregistered in {@link #hideWindow()}, but it's possible
         // for {@link #doFinishInput()} to be called without {@link #hideWindow()} so we also
         // unregister here.
-        // TODO(b/232341407): Add CTS to verify back behavior after screen on / off.
         unregisterCompatOnBackInvokedCallback();
     }
 
diff --git a/core/java/android/net/SntpClient.java b/core/java/android/net/SntpClient.java
index b05f7cf..0fb04b9 100644
--- a/core/java/android/net/SntpClient.java
+++ b/core/java/android/net/SntpClient.java
@@ -16,6 +16,7 @@
 
 package android.net;
 
+import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.net.sntp.Duration64;
 import android.net.sntp.Timestamp64;
@@ -29,6 +30,7 @@
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.net.UnknownHostException;
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
@@ -39,9 +41,7 @@
 import java.util.function.Supplier;
 
 /**
- * {@hide}
- *
- * Simple SNTP client class for retrieving network time.
+ * Simple, single-use SNTP client class for retrieving network time.
  *
  * Sample usage:
  * <pre>SntpClient client = new SntpClient();
@@ -49,6 +49,10 @@
  *     long now = client.getNtpTime() + SystemClock.elapsedRealtime() - client.getNtpTimeReference();
  * }
  * </pre>
+ *
+ * <p>This class is not thread-safe.
+ *
+ * @hide
  */
 public class SntpClient {
     private static final String TAG = "SntpClient";
@@ -87,6 +91,9 @@
     // The round trip (network) time in milliseconds
     private long mRoundTripTime;
 
+    // Details of the NTP server used to obtain the time last.
+    @Nullable private InetSocketAddress mServerSocketAddress;
+
     private static class InvalidServerReplyException extends Exception {
         public InvalidServerReplyException(String message) {
             super(message);
@@ -202,6 +209,7 @@
             mNtpTime = responseTime.plus(clockOffsetDuration).toEpochMilli();
             mNtpTimeReference = responseTicks;
             mRoundTripTime = roundTripTimeMillis;
+            mServerSocketAddress = new InetSocketAddress(address, port);
         } catch (Exception e) {
             EventLogTags.writeNtpFailure(address.toString(), e.toString());
             if (DBG) Log.d(TAG, "request time failed: " + e);
@@ -284,6 +292,14 @@
         return mRoundTripTime;
     }
 
+    /**
+     * Returns the address of the NTP server used in the NTP transaction
+     */
+    @Nullable
+    public InetSocketAddress getServerSocketAddress() {
+        return mServerSocketAddress;
+    }
+
     private static void checkValidServerReply(
             byte leap, byte mode, int stratum, Timestamp64 transmitTimestamp,
             Timestamp64 referenceTimestamp, Timestamp64 randomizedRequestTimestamp,
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index cc8e541..09a52e4 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -77,7 +77,7 @@
  * except where indicated otherwise.
  * @hide
  */
-public abstract class BatteryStats implements Parcelable {
+public abstract class BatteryStats {
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     public BatteryStats() {}
@@ -3516,8 +3516,6 @@
 
     public abstract LongSparseArray<? extends Timer> getKernelMemoryStats();
 
-    public abstract void writeToParcelWithoutUids(Parcel out, int flags);
-
     private final static void formatTimeRaw(StringBuilder out, long seconds) {
         long days = seconds / (60 * 60 * 24);
         if (days != 0) {
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/OutcomeReceiver.java b/core/java/android/os/OutcomeReceiver.java
index 01b2764..4b9552e 100644
--- a/core/java/android/os/OutcomeReceiver.java
+++ b/core/java/android/os/OutcomeReceiver.java
@@ -31,7 +31,7 @@
      * Called when the asynchronous operation succeeds and delivers a result value.
      * @param result The value delivered by the asynchronous operation.
      */
-    void onResult(@NonNull R result);
+    void onResult(R result);
 
     /**
      * Called when the asynchronous operation fails. The mode of failure is indicated by the
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/SystemClock.java b/core/java/android/os/SystemClock.java
index 7379443..ecea054 100644
--- a/core/java/android/os/SystemClock.java
+++ b/core/java/android/os/SystemClock.java
@@ -18,6 +18,8 @@
 
 import android.annotation.NonNull;
 import android.app.IAlarmManager;
+import android.app.timedetector.ITimeDetectorService;
+import android.app.timedetector.TimePoint;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.location.ILocationManager;
@@ -170,6 +172,14 @@
         return false;
     }
 
+    private static IAlarmManager getIAlarmManager() {
+        if (sIAlarmManager == null) {
+            sIAlarmManager = IAlarmManager.Stub
+                    .asInterface(ServiceManager.getService(Context.ALARM_SERVICE));
+        }
+        return sIAlarmManager;
+    }
+
     /**
      * Returns milliseconds since boot, not counting time spent in deep sleep.
      *
@@ -269,56 +279,71 @@
      * <p>
      * While the time returned by {@link System#currentTimeMillis()} can be
      * adjusted by the user, the time returned by this method cannot be adjusted
-     * by the user. Note that synchronization may occur using an insecure
-     * network protocol, so the returned time should not be used for security
-     * purposes.
+     * by the user.
      * <p>
      * This performs no blocking network operations and returns values based on
      * a recent successful synchronization event; it will either return a valid
      * time or throw.
+     * <p>
+     * Note that synchronization may occur using an insecure network protocol,
+     * so the returned time should not be used for security purposes.
+     * The device may resynchronize with the same or different network source
+     * at any time. Due to network delays, variations between servers, or local
+     * (client side) clock drift, the accuracy of the returned times cannot be
+     * guaranteed. In extreme cases, consecutive calls to {@link
+     * #currentNetworkTimeMillis()} could return times that are out of order.
      *
-     * @throws DateTimeException when no accurate network time can be provided.
+     * @throws DateTimeException when no network time can be provided.
      * @hide
      */
     public static long currentNetworkTimeMillis() {
-        final IAlarmManager mgr = getIAlarmManager();
-        if (mgr != null) {
+        ITimeDetectorService timeDetectorService = ITimeDetectorService.Stub
+                .asInterface(ServiceManager.getService(Context.TIME_DETECTOR_SERVICE));
+        if (timeDetectorService != null) {
+            TimePoint time;
             try {
-                return mgr.currentNetworkTimeMillis();
+                time = timeDetectorService.latestNetworkTime();
             } catch (ParcelableException e) {
                 e.maybeRethrow(DateTimeException.class);
                 throw new RuntimeException(e);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
+
+            if (time == null) {
+                // This is not expected.
+                throw new DateTimeException("Network based time is not available.");
+            }
+            long currentMillis = elapsedRealtime();
+            long deltaMs = currentMillis - time.getElapsedRealtimeMillis();
+            return time.getUnixEpochTimeMillis() + deltaMs;
         } else {
             throw new RuntimeException(new DeadSystemException());
         }
     }
 
-    private static IAlarmManager getIAlarmManager() {
-        if (sIAlarmManager == null) {
-            sIAlarmManager = IAlarmManager.Stub
-                    .asInterface(ServiceManager.getService(Context.ALARM_SERVICE));
-        }
-        return sIAlarmManager;
-    }
-
-    /**
+   /**
      * Returns a {@link Clock} that starts at January 1, 1970 00:00:00.0 UTC,
      * synchronized using a remote network source outside the device.
      * <p>
      * While the time returned by {@link System#currentTimeMillis()} can be
      * adjusted by the user, the time returned by this method cannot be adjusted
-     * by the user. Note that synchronization may occur using an insecure
-     * network protocol, so the returned time should not be used for security
-     * purposes.
+     * by the user.
      * <p>
      * This performs no blocking network operations and returns values based on
      * a recent successful synchronization event; it will either return a valid
      * time or throw.
+     * <p>
+     * Note that synchronization may occur using an insecure network protocol,
+     * so the returned time should not be used for security purposes.
+     * The device may resynchronize with the same or different network source
+     * at any time. Due to network delays, variations between servers, or local
+     * (client side) clock drift, the accuracy of the returned times cannot be
+     * guaranteed. In extreme cases, consecutive calls to {@link
+     * Clock#millis()} on the returned {@link Clock}could return times that are
+     * out of order.
      *
-     * @throws DateTimeException when no accurate network time can be provided.
+     * @throws DateTimeException when no network time can be provided.
      */
     public static @NonNull Clock currentNetworkTimeClock() {
         return new SimpleClock(ZoneOffset.UTC) {
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/provider/Settings.java b/core/java/android/provider/Settings.java
index 6c5066f..6fc2811 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -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
          */
@@ -10950,6 +10987,14 @@
         public static final String ADAPTIVE_CHARGING_ENABLED = "adaptive_charging_enabled";
 
         /**
+         * Whether battery saver is currently set to different schedule mode.
+         *
+         * @hide
+         */
+        public static final String EXTRA_AUTOMATIC_POWER_SAVE_MODE =
+                "extra_automatic_power_save_mode";
+
+        /**
          * These entries are considered common between the personal and the managed profile,
          * since the managed profile doesn't get to change them.
          */
@@ -11371,6 +11416,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.
          */
@@ -11998,10 +12044,41 @@
         public static final String NITZ_NETWORK_DISCONNECT_RETENTION =
                 "nitz_network_disconnect_retention";
 
-        /** Preferred NTP server. {@hide} */
+        /**
+         * SNTP client config: The preferred NTP server. This setting overrides the static
+         * config.xml configuration when present and valid.
+         *
+         * <p>The legacy form is the NTP server name as a string.
+         * <p>Newer code should use the form: ntp://{server name}[:port] (the standard NTP port,
+         * 123, is used if not specified).
+         *
+         * <p>The settings value can consist of a pipe ("|") delimited list of server names or
+         * ntp:// URIs. When present, all server name / ntp:// URIs must be valid or the entire
+         * setting value will be ignored and Android's xml config will be used.
+         *
+         * <p>For example, the following examples are valid:
+         * <ul>
+         *     <li>"time.android.com"</li>
+         *     <li>"ntp://time.android.com"</li>
+         *     <li>"ntp://time.android.com:123"</li>
+         *     <li>"time.android.com|time.other"</li>
+         *     <li>"ntp://time.android.com:123|ntp://time.other:123"</li>
+         *     <li>"time.android.com|ntp://time.other:123"</li>
+         * </ul>
+         *
+         * @hide
+         */
         @Readable
         public static final String NTP_SERVER = "ntp_server";
-        /** Timeout in milliseconds to wait for NTP server. {@hide} */
+
+        /**
+         * SNTP client config: Timeout to wait for an NTP server response. This setting overrides
+         * the static config.xml configuration when present and valid.
+         *
+         * <p>The value is the timeout in milliseconds. It must be > 0.
+         *
+         * @hide
+         */
         @Readable
         public static final String NTP_TIMEOUT = "ntp_timeout";
 
@@ -17431,7 +17508,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/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/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/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index f1ce9c3..eae951f 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -107,6 +107,15 @@
      */
     public static final String SETTINGS_ENABLE_CLEAR_CALLING = "settings_enable_clear_calling";
 
+
+    /** Flag to enable / disable the Simple Cursor accessibility feature in
+     *  Settings.
+     * @hide
+     */
+    public static final String SETTINGS_ACCESSIBILITY_SIMPLE_CURSOR =
+            "settings_accessibility_simple_cursor";
+
+
     private static final Map<String, String> DEFAULT_FLAGS;
 
     static {
@@ -138,6 +147,7 @@
         DEFAULT_FLAGS.put(SETTINGS_AUTO_TEXT_WRAPPING, "false");
         DEFAULT_FLAGS.put(SETTINGS_GUEST_MODE_UX_CHANGES, "true");
         DEFAULT_FLAGS.put(SETTINGS_ENABLE_CLEAR_CALLING, "false");
+        DEFAULT_FLAGS.put(SETTINGS_ACCESSIBILITY_SIMPLE_CURSOR, "false");
     }
 
     private static final Set<String> PERSISTENT_FLAGS;
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java
index b5fe4f5..f1e91d0 100644
--- a/core/java/android/util/Log.java
+++ b/core/java/android/util/Log.java
@@ -66,6 +66,10 @@
  * <p>When calling the log methods that take a Throwable parameter,
  * if any of the throwables in the cause chain is an <code>UnknownHostException</code>,
  * then the stack trace is not logged.
+ *
+ * <p>Note: The return value from the logging functions in this class may vary between Android
+ * releases due to changes in the logging implementation. For the methods that return an integer,
+ * a positive value may be considered as a successful invocation.
  */
 public final class Log {
     /** @hide */
@@ -134,6 +138,7 @@
      * @param tag Used to identify the source of a log message.  It usually identifies
      *        the class or activity where the log call occurs.
      * @param msg The message you would like logged.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
      */
     public static int v(@Nullable String tag, @NonNull String msg) {
         return println_native(LOG_ID_MAIN, VERBOSE, tag, msg);
@@ -144,7 +149,8 @@
      * @param tag Used to identify the source of a log message.  It usually identifies
      *        the class or activity where the log call occurs.
      * @param msg The message you would like logged.
-     * @param tr An exception to log
+     * @param tr An exception to log.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
      */
     public static int v(@Nullable String tag, @Nullable String msg, @Nullable Throwable tr) {
         return printlns(LOG_ID_MAIN, VERBOSE, tag, msg, tr);
@@ -155,6 +161,7 @@
      * @param tag Used to identify the source of a log message.  It usually identifies
      *        the class or activity where the log call occurs.
      * @param msg The message you would like logged.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
      */
     public static int d(@Nullable String tag, @NonNull String msg) {
         return println_native(LOG_ID_MAIN, DEBUG, tag, msg);
@@ -165,7 +172,8 @@
      * @param tag Used to identify the source of a log message.  It usually identifies
      *        the class or activity where the log call occurs.
      * @param msg The message you would like logged.
-     * @param tr An exception to log
+     * @param tr An exception to log.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
      */
     public static int d(@Nullable String tag, @Nullable String msg, @Nullable Throwable tr) {
         return printlns(LOG_ID_MAIN, DEBUG, tag, msg, tr);
@@ -176,6 +184,7 @@
      * @param tag Used to identify the source of a log message.  It usually identifies
      *        the class or activity where the log call occurs.
      * @param msg The message you would like logged.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
      */
     public static int i(@Nullable String tag, @NonNull String msg) {
         return println_native(LOG_ID_MAIN, INFO, tag, msg);
@@ -186,7 +195,7 @@
      * @param tag Used to identify the source of a log message.  It usually identifies
      *        the class or activity where the log call occurs.
      * @param msg The message you would like logged.
-     * @param tr An exception to log
+     * @param tr An exception to log.
      */
     public static int i(@Nullable String tag, @Nullable String msg, @Nullable Throwable tr) {
         return printlns(LOG_ID_MAIN, INFO, tag, msg, tr);
@@ -197,6 +206,7 @@
      * @param tag Used to identify the source of a log message.  It usually identifies
      *        the class or activity where the log call occurs.
      * @param msg The message you would like logged.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
      */
     public static int w(@Nullable String tag, @NonNull String msg) {
         return println_native(LOG_ID_MAIN, WARN, tag, msg);
@@ -207,7 +217,8 @@
      * @param tag Used to identify the source of a log message.  It usually identifies
      *        the class or activity where the log call occurs.
      * @param msg The message you would like logged.
-     * @param tr An exception to log
+     * @param tr An exception to log.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
      */
     public static int w(@Nullable String tag, @Nullable String msg, @Nullable Throwable tr) {
         return printlns(LOG_ID_MAIN, WARN, tag, msg, tr);
@@ -239,7 +250,8 @@
      * Send a {@link #WARN} log message and log the exception.
      * @param tag Used to identify the source of a log message.  It usually identifies
      *        the class or activity where the log call occurs.
-     * @param tr An exception to log
+     * @param tr An exception to log.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
      */
     public static int w(@Nullable String tag, @Nullable Throwable tr) {
         return printlns(LOG_ID_MAIN, WARN, tag, "", tr);
@@ -250,6 +262,7 @@
      * @param tag Used to identify the source of a log message.  It usually identifies
      *        the class or activity where the log call occurs.
      * @param msg The message you would like logged.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
      */
     public static int e(@Nullable String tag, @NonNull String msg) {
         return println_native(LOG_ID_MAIN, ERROR, tag, msg);
@@ -260,7 +273,8 @@
      * @param tag Used to identify the source of a log message.  It usually identifies
      *        the class or activity where the log call occurs.
      * @param msg The message you would like logged.
-     * @param tr An exception to log
+     * @param tr An exception to log.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
      */
     public static int e(@Nullable String tag, @Nullable String msg, @Nullable Throwable tr) {
         return printlns(LOG_ID_MAIN, ERROR, tag, msg, tr);
@@ -274,6 +288,7 @@
      * immediately with an error dialog.
      * @param tag Used to identify the source of a log message.
      * @param msg The message you would like logged.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
      */
     public static int wtf(@Nullable String tag, @Nullable String msg) {
         return wtf(LOG_ID_MAIN, tag, msg, null, false, false);
@@ -293,6 +308,7 @@
      * Similar to {@link #wtf(String, String)}, with an exception to log.
      * @param tag Used to identify the source of a log message.
      * @param tr An exception to log.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
      */
     public static int wtf(@Nullable String tag, @NonNull Throwable tr) {
         return wtf(LOG_ID_MAIN, tag, tr.getMessage(), tr, false, false);
@@ -304,6 +320,7 @@
      * @param tag Used to identify the source of a log message.
      * @param msg The message you would like logged.
      * @param tr An exception to log.  May be null.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
      */
     public static int wtf(@Nullable String tag, @Nullable String msg, @Nullable Throwable tr) {
         return wtf(LOG_ID_MAIN, tag, msg, tr, false, false);
@@ -348,7 +365,7 @@
 
      * <p>If any of the throwables in the cause chain is an <code>UnknownHostException</code>,
      * this returns an empty string.
-     * @param tr An exception to log
+     * @param tr An exception to log.
      */
     @NonNull
     public static String getStackTraceString(@Nullable Throwable tr) {
@@ -379,7 +396,7 @@
      * @param tag Used to identify the source of a log message.  It usually identifies
      *        the class or activity where the log call occurs.
      * @param msg The message you would like logged.
-     * @return The number of bytes written.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
      */
     public static int println(@Level int priority, @Nullable String tag, @NonNull String msg) {
         return println_native(LOG_ID_MAIN, priority, tag, msg);
@@ -391,7 +408,16 @@
     /** @hide */ public static final int LOG_ID_SYSTEM = 3;
     /** @hide */ public static final int LOG_ID_CRASH = 4;
 
-    /** @hide */
+    /**
+     * Low-level logging call.
+     * @param bufID The buffer ID to receive the message.
+     * @param priority The priority of the message.
+     * @param tag Used to identify the source of a log message.  It usually identifies
+     *        the class or activity where the log call occurs.
+     * @param msg The message you would like logged.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
+     * @hide
+     */
     @UnsupportedAppUsage
     public static native int println_native(int bufID, int priority, String tag, String msg);
 
@@ -407,6 +433,7 @@
      * @param tag Used to identify the source of a log message.  It usually identifies
      *        the class or activity where the log call occurs.
      * @param message The message you would like logged.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
      * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@@ -425,6 +452,7 @@
      * Helper function for long messages. Uses the LineBreakBufferedWriter to break
      * up long messages and stacktraces along newlines, but tries to write in large
      * chunks. This is to avoid truncation.
+     * @return A positive value if the message was loggable (see {@link #isLoggable}).
      * @hide
      */
     public static int printlns(int bufID, int priority, @Nullable String tag, @NonNull String msg,
diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java
index 4e7b3a5..af43222 100644
--- a/core/java/android/util/NtpTrustedTime.java
+++ b/core/java/android/util/NtpTrustedTime.java
@@ -32,12 +32,18 @@
 import android.text.TextUtils;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.PrintWriter;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.time.Duration;
 import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.Objects;
-import java.util.function.Supplier;
 
 /**
  * A singleton that connects with a remote NTP server as its trusted time source. This class
@@ -47,39 +53,114 @@
  *
  * @hide
  */
-public class NtpTrustedTime implements TrustedTime {
+public abstract class NtpTrustedTime implements TrustedTime {
+
+    private static final String URI_SCHEME_NTP = "ntp";
+    @VisibleForTesting
+    public static final String NTP_SETTING_SERVER_NAME_DELIMITER = "|";
+    private static final String NTP_SETTING_SERVER_NAME_DELIMITER_REGEXP = "\\|";
+
+    /**
+     * NTP server configuration.
+     *
+     * @hide
+     */
+    public static final class NtpConfig {
+
+        @NonNull private final List<URI> mServerUris;
+        @NonNull private final Duration mTimeout;
+
+        /**
+         * Creates an instance with the supplied properties. There must be at least one NTP server
+         * URI and the timeout must be non-zero / non-negative.
+         *
+         * <p>If the arguments are invalid then an {@link IllegalArgumentException} will be thrown.
+         * See {@link #parseNtpUriStrict(String)} and {@link #parseNtpServerSetting(String)} to
+         * create valid URIs.
+         */
+        public NtpConfig(@NonNull List<URI> serverUris, @NonNull Duration timeout)
+                throws IllegalArgumentException {
+
+            Objects.requireNonNull(serverUris);
+            if (serverUris.isEmpty()) {
+                throw new IllegalArgumentException("Server URIs is empty");
+            }
+
+            List<URI> validatedServerUris = new ArrayList<>();
+            for (URI serverUri : serverUris) {
+                try {
+                    URI validatedServerUri = validateNtpServerUri(
+                            Objects.requireNonNull(serverUri));
+                    validatedServerUris.add(validatedServerUri);
+                } catch (URISyntaxException e) {
+                    throw new IllegalArgumentException("Bad server URI", e);
+                }
+            }
+            mServerUris = Collections.unmodifiableList(validatedServerUris);
+
+            if (timeout.isNegative() || timeout.isZero()) {
+                throw new IllegalArgumentException("timeout < 0");
+            }
+            mTimeout = timeout;
+        }
+
+        /** Returns a non-empty, immutable list of NTP server URIs. */
+        @NonNull
+        public List<URI> getServerUris() {
+            return mServerUris;
+        }
+
+        @NonNull
+        public Duration getTimeout() {
+            return mTimeout;
+        }
+
+        @Override
+        public String toString() {
+            return "NtpConnectionInfo{"
+                    + "mServerUris=" + mServerUris
+                    + ", mTimeout=" + mTimeout
+                    + '}';
+        }
+    }
 
     /**
      * The result of a successful NTP query.
      *
      * @hide
      */
-    public static class TimeResult {
-        private final long mTimeMillis;
+    public static final class TimeResult {
+        private final long mUnixEpochTimeMillis;
         private final long mElapsedRealtimeMillis;
-        private final long mCertaintyMillis;
+        private final int mUncertaintyMillis;
+        @NonNull private final InetSocketAddress mNtpServerSocketAddress;
 
-        public TimeResult(long timeMillis, long elapsedRealtimeMillis, long certaintyMillis) {
-            mTimeMillis = timeMillis;
+        public TimeResult(
+                long unixEpochTimeMillis, long elapsedRealtimeMillis, int uncertaintyMillis,
+                @NonNull InetSocketAddress ntpServerSocketAddress) {
+            mUnixEpochTimeMillis = unixEpochTimeMillis;
             mElapsedRealtimeMillis = elapsedRealtimeMillis;
-            mCertaintyMillis = certaintyMillis;
+            mUncertaintyMillis = uncertaintyMillis;
+            mNtpServerSocketAddress = Objects.requireNonNull(ntpServerSocketAddress);
         }
 
         public long getTimeMillis() {
-            return mTimeMillis;
+            return mUnixEpochTimeMillis;
         }
 
         public long getElapsedRealtimeMillis() {
             return mElapsedRealtimeMillis;
         }
 
-        public long getCertaintyMillis() {
-            return mCertaintyMillis;
+        public int getUncertaintyMillis() {
+            return mUncertaintyMillis;
         }
 
-        /** Calculates and returns the current time accounting for the age of this result. */
+        /**
+         * Calculates and returns the current Unix epoch time accounting for the age of this result.
+         */
         public long currentTimeMillis() {
-            return mTimeMillis + getAgeMillis();
+            return mUnixEpochTimeMillis + getAgeMillis();
         }
 
         /** Calculates and returns the age of this result. */
@@ -97,11 +178,34 @@
         }
 
         @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (!(o instanceof TimeResult)) {
+                return false;
+            }
+            TimeResult that = (TimeResult) o;
+            return mUnixEpochTimeMillis == that.mUnixEpochTimeMillis
+                    && mElapsedRealtimeMillis == that.mElapsedRealtimeMillis
+                    && mUncertaintyMillis == that.mUncertaintyMillis
+                    && mNtpServerSocketAddress.equals(
+                    that.mNtpServerSocketAddress);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mUnixEpochTimeMillis, mElapsedRealtimeMillis, mUncertaintyMillis,
+                    mNtpServerSocketAddress);
+        }
+
+        @Override
         public String toString() {
             return "TimeResult{"
-                    + "mTimeMillis=" + Instant.ofEpochMilli(mTimeMillis)
-                    + ", mElapsedRealtimeMillis=" + Duration.ofMillis(mElapsedRealtimeMillis)
-                    + ", mCertaintyMillis=" + mCertaintyMillis
+                    + "unixEpochTime=" + Instant.ofEpochMilli(mUnixEpochTimeMillis)
+                    + ", elapsedRealtime=" + Duration.ofMillis(mElapsedRealtimeMillis)
+                    + ", mUncertaintyMillis=" + mUncertaintyMillis
+                    + ", mNtpServerSocketAddress=" + mNtpServerSocketAddress
                     + '}';
         }
     }
@@ -111,54 +215,27 @@
 
     private static NtpTrustedTime sSingleton;
 
-    @NonNull
-    private final Context mContext;
-
-    /**
-     * A supplier that returns the ConnectivityManager. The Supplier can return null if
-     * ConnectivityService isn't running yet.
-     */
-    private final Supplier<ConnectivityManager> mConnectivityManagerSupplier =
-            new Supplier<ConnectivityManager>() {
-        private ConnectivityManager mConnectivityManager;
-
-        @Nullable
-        @Override
-        public synchronized ConnectivityManager get() {
-            // We can't do this at initialization time: ConnectivityService might not be running
-            // yet.
-            if (mConnectivityManager == null) {
-                mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
-            }
-            return mConnectivityManager;
-        }
-    };
-
     /** An in-memory config override for use during tests. */
+    @GuardedBy("this")
     @Nullable
-    private String mHostnameForTests;
+    private NtpConfig mNtpConfigForTests;
 
-    /** An in-memory config override for use during tests. */
+    @GuardedBy("this")
     @Nullable
-    private Integer mPortForTests;
+    private URI mLastSuccessfulNtpServerUri;
 
-    /** An in-memory config override for use during tests. */
-    @Nullable
-    private Duration mTimeoutForTests;
-
-    // Declared volatile and accessed outside of synchronized blocks to avoid blocking reads during
+    // Declared volatile and accessed outside synchronized blocks to avoid blocking reads during
     // forceRefresh().
     private volatile TimeResult mTimeResult;
 
-    private NtpTrustedTime(Context context) {
-        mContext = Objects.requireNonNull(context);
+    protected NtpTrustedTime() {
     }
 
     @UnsupportedAppUsage
     public static synchronized NtpTrustedTime getInstance(Context context) {
         if (sSingleton == null) {
             Context appContext = context.getApplicationContext();
-            sSingleton = new NtpTrustedTime(appContext);
+            sSingleton = new NtpTrustedTimeImpl(appContext);
         }
         return sSingleton;
     }
@@ -167,63 +244,158 @@
      * Overrides the NTP server config for tests. Passing {@code null} to a parameter clears the
      * test value, i.e. so the normal value will be used next time.
      */
-    public void setServerConfigForTests(
-            @Nullable String hostname, @Nullable Integer port, @Nullable Duration timeout) {
+    public void setServerConfigForTests(@NonNull NtpConfig ntpConfig) {
         synchronized (this) {
-            mHostnameForTests = hostname;
-            mPortForTests = port;
-            mTimeoutForTests = timeout;
+            mNtpConfigForTests = ntpConfig;
         }
     }
 
+    /** Forces a refresh using the default network. */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public boolean forceRefresh() {
         synchronized (this) {
-            NtpConnectionInfo connectionInfo = getNtpConnectionInfo();
-            if (connectionInfo == null) {
-                // missing server config, so no NTP time available
-                if (LOGD) Log.d(TAG, "forceRefresh: invalid server config");
+            Network network = getDefaultNetwork();
+            if (network == null) {
+                if (LOGD) Log.d(TAG, "forceRefresh: no network available");
                 return false;
             }
 
-            ConnectivityManager connectivityManager = mConnectivityManagerSupplier.get();
-            if (connectivityManager == null) {
-                if (LOGD) Log.d(TAG, "forceRefresh: no ConnectivityManager");
-                return false;
-            }
-            final Network network = connectivityManager.getActiveNetwork();
-            final NetworkInfo ni = connectivityManager.getNetworkInfo(network);
-
-            // This connectivity check is to avoid performing a DNS lookup for the time server on a
-            // unconnected network. There are races to obtain time in Android when connectivity
-            // changes, which means that forceRefresh() can be called by various components before
-            // the network is actually available. This led in the past to DNS lookup failures being
-            // cached (~2 seconds) thereby preventing the device successfully making an NTP request
-            // when connectivity had actually been established.
-            // A side effect of check is that tests that run a fake NTP server on the device itself
-            // will only be able to use it if the active network is connected, even though loopback
-            // addresses are actually reachable.
-            if (ni == null || !ni.isConnected()) {
-                if (LOGD) Log.d(TAG, "forceRefresh: no connectivity");
-                return false;
-            }
-
-            if (LOGD) Log.d(TAG, "forceRefresh() from cache miss");
-            final SntpClient client = new SntpClient();
-            final String serverName = connectionInfo.getServer();
-            final int port = connectionInfo.getPort();
-            final int timeoutMillis = connectionInfo.getTimeoutMillis();
-            if (client.requestTime(serverName, port, timeoutMillis, network)) {
-                long ntpCertainty = client.getRoundTripTime() / 2;
-                mTimeResult = new TimeResult(
-                        client.getNtpTime(), client.getNtpTimeReference(), ntpCertainty);
-                return true;
-            } else {
-                return false;
-            }
+            return forceRefreshLocked(network);
         }
     }
 
+    /** Forces a refresh using the specified network. */
+    public boolean forceRefresh(@NonNull Network network) {
+        Objects.requireNonNull(network);
+
+        synchronized (this) {
+            return forceRefreshLocked(network);
+        }
+    }
+
+    @GuardedBy("this")
+    private boolean forceRefreshLocked(@NonNull Network network) {
+        Objects.requireNonNull(network);
+
+        if (!isNetworkConnected(network)) {
+            if (LOGD) Log.d(TAG, "forceRefreshLocked: network=" + network + " is not connected");
+            return false;
+        }
+
+        NtpConfig ntpConfig = getNtpConfig();
+        if (ntpConfig == null) {
+            // missing server config, so no NTP time available
+            if (LOGD) Log.d(TAG, "forceRefreshLocked: invalid server config");
+            return false;
+        }
+
+        if (LOGD) {
+            Log.d(TAG, "forceRefreshLocked: NTP request network=" + network
+                    + " ntpConfig=" + ntpConfig);
+        }
+
+        List<URI> unorderedServerUris = ntpConfig.getServerUris();
+
+        // Android supports multiple NTP server URIs for situations where servers might be
+        // unreachable for some devices due to network topology, e.g. we understand that devices
+        // travelling to China often have difficulty accessing "time.android.com". Android
+        // partners may want to configure alternative URIs for devices sold globally, or those
+        // that are likely to travel to part of the world without access to the full internet.
+        //
+        // The server URI list is expected to contain one element in the general case, with two
+        // or three as the anticipated maximum. The list is never empty. Server URIs are
+        // considered to be in a rough priority order of servers to try initially (no
+        // randomization), but besides that there is assumed to be no preference.
+        //
+        // The server selection algorithm below tries to stick with a successfully accessed NTP
+        // server's URI where possible:
+        //
+        // The algorithm based on the assumption that a cluster of NTP servers sharing the same
+        // host name, particularly commercially run ones, are likely to agree more closely on
+        // the time than servers from different URIs, so it's best to be sticky. Switching
+        // between URIs could result in flip-flopping between reference clocks or involve
+        // talking to server clusters with different approaches to leap second handling.
+        //
+        // Stickiness may also be useful if some server URIs early in the list are permanently
+        // black-holing requests, or if the responses are not routed back. In those cases it's
+        // best not to try those URIs more than we have to, as might happen if the algorithm
+        // always started at the beginning of the list.
+        //
+        // Generally, we have to assume that any of the configured servers are going to be "good
+        // enough" as an external reference clock when reachable, so the stickiness is a very
+        // lightly applied bias. There's no tracking of failure rates or back-off on a per-URI
+        // basis; higher level code is expected to handle rate limiting of NTP requests in the
+        // event of failure to contact any server.
+
+        List<URI> orderedServerUris = new ArrayList<>();
+        for (URI serverUri : unorderedServerUris) {
+            if (serverUri.equals(mLastSuccessfulNtpServerUri)) {
+                orderedServerUris.add(0, serverUri);
+            } else {
+                orderedServerUris.add(serverUri);
+            }
+        }
+
+        for (URI serverUri : orderedServerUris) {
+            TimeResult timeResult = queryNtpServer(network, serverUri, ntpConfig.getTimeout());
+            // Only overwrite previous state if the request was successful.
+            if (timeResult != null) {
+                mLastSuccessfulNtpServerUri = serverUri;
+                mTimeResult = timeResult;
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @GuardedBy("this")
+    private NtpConfig getNtpConfig() {
+        if (mNtpConfigForTests != null) {
+            return mNtpConfigForTests;
+        }
+        return getNtpConfigInternal();
+    }
+
+    /**
+     * Returns the {@link NtpConfig} to use during an NTP query. This method can return {@code null}
+     * if there is no config, or the config found is invalid.
+     *
+     * <p>This method has been made public for easy replacement during tests.
+     */
+    @VisibleForTesting
+    @Nullable
+    public abstract NtpConfig getNtpConfigInternal();
+
+    /**
+     * Returns the default {@link Network} to use during an NTP query when no network is specified.
+     * This method can return {@code null} if the device hasn't fully initialized or there is no
+     * active network.
+     *
+     * <p>This method has been made public for easy replacement during tests.
+     */
+    @VisibleForTesting
+    @Nullable
+    public abstract Network getDefaultNetwork();
+
+    /**
+     * Returns {@code true} if there is likely to be connectivity on the supplied network.
+     *
+     * <p>This method has been made public for easy replacement during tests.
+     */
+    @VisibleForTesting
+    public abstract boolean isNetworkConnected(@NonNull Network network);
+
+    /**
+     * Queries the specified NTP server. This is a blocking call. Returns {@code null} if the query
+     * fails.
+     *
+     * <p>This method has been made public for easy replacement during tests.
+     */
+    @VisibleForTesting
+    @Nullable
+    public abstract TimeResult queryNtpServer(
+            @NonNull Network network, @NonNull URI ntpServerUri, @NonNull Duration timeout);
+
     /**
      * Only kept for UnsupportedAppUsage.
      *
@@ -311,85 +483,104 @@
         }
     }
 
-    private static class NtpConnectionInfo {
+    /**
+     * Parses and returns an NTP server config URI, or throws an exception if the URI doesn't
+     * conform to expectations.
+     *
+     * <p>NTP server config URIs are in the form "ntp://{hostname}[:port]". This is not a registered
+     * IANA URI scheme.
+     */
+    @NonNull
+    public static URI parseNtpUriStrict(@NonNull String ntpServerUriString)
+            throws URISyntaxException {
+        // java.net.URI is used in preference to android.net.Uri, since android.net.Uri is very
+        // forgiving of obvious errors. URI catches issues sooner.
+        URI unvalidatedUri = new URI(ntpServerUriString);
+        return validateNtpServerUri(unvalidatedUri);
+    }
 
-        @NonNull private final String mServer;
-        private final int mPort;
-        private final int mTimeoutMillis;
+    /**
+     * Parses a setting string and returns a list of URIs that will be accepted by {@link
+     * NtpConfig}, or {@code null} if the string is invalid.
+     *
+     * <p>The setting string is expected to be one or more server values separated by a pipe ("|")
+     * character.
+     *
+     * <p>NTP server config URIs are in the form "ntp://{hostname}[:port]". This is not a registered
+     * IANA URI scheme.
+     *
+     * <p>Unlike {@link #parseNtpUriStrict(String)} this method will not throw an exception. It
+     * checks each value for a leading "ntp:" and will call through to {@link
+     * #parseNtpUriStrict(String)} to attempt to parse it, returning {@code null} if it fails.
+     * To support legacy settings values, it will also accept string values that only consists of a
+     * server name, which will be coerced into a URI in the form "ntp://{server name}".
+     */
+    @VisibleForTesting
+    @Nullable
+    public static List<URI> parseNtpServerSetting(@Nullable String ntpServerSetting) {
+        if (TextUtils.isEmpty(ntpServerSetting)) {
+            return null;
+        } else {
+            String[] values = ntpServerSetting.split(NTP_SETTING_SERVER_NAME_DELIMITER_REGEXP);
+            if (values.length == 0) {
+                return null;
+            }
 
-        NtpConnectionInfo(@NonNull String server, int port, int timeoutMillis) {
-            mServer = Objects.requireNonNull(server);
-            mPort = port;
-            mTimeoutMillis = timeoutMillis;
-        }
-
-        @NonNull
-        public String getServer() {
-            return mServer;
-        }
-
-        @NonNull
-        public int getPort() {
-            return mPort;
-        }
-
-        int getTimeoutMillis() {
-            return mTimeoutMillis;
-        }
-
-        @Override
-        public String toString() {
-            return "NtpConnectionInfo{"
-                    + "mServer='" + mServer + '\''
-                    + ", mPort='" + mPort + '\''
-                    + ", mTimeoutMillis=" + mTimeoutMillis
-                    + '}';
+            List<URI> uris = new ArrayList<>();
+            for (String value : values) {
+                if (value.startsWith(URI_SCHEME_NTP + ":")) {
+                    try {
+                        uris.add(parseNtpUriStrict(value));
+                    } catch (URISyntaxException e) {
+                        Log.w(TAG, "Rejected NTP uri setting=" + ntpServerSetting, e);
+                        return null;
+                    }
+                } else {
+                    // This is the legacy settings path. Assumes that the string is just a host name
+                    // and creates a URI in the form ntp://<host name>
+                    try {
+                        URI uri = new URI(URI_SCHEME_NTP, /*host=*/value,
+                                /*path=*/null, /*fragment=*/null);
+                        // Paranoia: validate just in case the host name somehow results in a bad
+                        // URI.
+                        URI validatedUri = validateNtpServerUri(uri);
+                        uris.add(validatedUri);
+                    } catch (URISyntaxException e) {
+                        Log.w(TAG, "Rejected NTP legacy setting=" + ntpServerSetting, e);
+                        return null;
+                    }
+                }
+            }
+            return uris;
         }
     }
 
-    @GuardedBy("this")
-    private NtpConnectionInfo getNtpConnectionInfo() {
-        final ContentResolver resolver = mContext.getContentResolver();
-
-        final Resources res = mContext.getResources();
-
-        final String hostname;
-        if (mHostnameForTests != null) {
-            hostname = mHostnameForTests;
-        } else {
-            String serverGlobalSetting =
-                    Settings.Global.getString(resolver, Settings.Global.NTP_SERVER);
-            if (serverGlobalSetting != null) {
-                hostname = serverGlobalSetting;
-            } else {
-                hostname = res.getString(com.android.internal.R.string.config_ntpServer);
-            }
+    /**
+     * Checks that the supplied URI can be used to identify an NTP server.
+     * This method currently ignores Uri components that are not used, only checking the parts that
+     * must be present. Returns the supplied {@code uri} if validation is successful.
+     */
+    @NonNull
+    private static URI validateNtpServerUri(@NonNull URI uri) throws URISyntaxException {
+        if (!uri.isAbsolute()) {
+            throw new URISyntaxException(uri.toString(), "Relative URI not supported");
         }
-
-        final Integer port;
-        if (mPortForTests != null) {
-            port = mPortForTests;
-        } else {
-            port = SntpClient.STANDARD_NTP_PORT;
+        if (!URI_SCHEME_NTP.equals(uri.getScheme())) {
+            throw new URISyntaxException(uri.toString(), "Unrecognized scheme");
         }
-
-        final int timeoutMillis;
-        if (mTimeoutForTests != null) {
-            timeoutMillis = (int) mTimeoutForTests.toMillis();
-        } else {
-            int defaultTimeoutMillis =
-                    res.getInteger(com.android.internal.R.integer.config_ntpTimeout);
-            timeoutMillis = Settings.Global.getInt(
-                    resolver, Settings.Global.NTP_TIMEOUT, defaultTimeoutMillis);
+        String host = uri.getHost();
+        if (TextUtils.isEmpty(host)) {
+            throw new URISyntaxException(uri.toString(), "Missing host");
         }
-        return TextUtils.isEmpty(hostname) ? null :
-            new NtpConnectionInfo(hostname, port, timeoutMillis);
+        return uri;
     }
 
     /** Prints debug information. */
     public void dump(PrintWriter pw) {
         synchronized (this) {
-            pw.println("getNtpConnectionInfo()=" + getNtpConnectionInfo());
+            pw.println("getNtpConfig()=" + getNtpConfig());
+            pw.println("mNtpConfigForTests=" + mNtpConfigForTests);
+            pw.println("mLastSuccessfulNtpServerUri=" + mLastSuccessfulNtpServerUri);
             pw.println("mTimeResult=" + mTimeResult);
             if (mTimeResult != null) {
                 pw.println("mTimeResult.getAgeMillis()="
@@ -397,4 +588,134 @@
             }
         }
     }
+
+    /**
+     * The real implementation of {@link NtpTrustedTime}. Contains the parts that are more difficult
+     * to test.
+     */
+    private static final class NtpTrustedTimeImpl extends NtpTrustedTime {
+
+        @GuardedBy("this")
+        private ConnectivityManager mConnectivityManager;
+
+        @NonNull
+        private final Context mContext;
+
+        private NtpTrustedTimeImpl(@NonNull Context context) {
+            mContext = Objects.requireNonNull(context);
+        }
+
+        @Override
+        @VisibleForTesting
+        @Nullable
+        public NtpConfig getNtpConfigInternal() {
+            final ContentResolver resolver = mContext.getContentResolver();
+            final Resources res = mContext.getResources();
+
+            // The Settings value has priority over static config. Check settings first.
+            final String serverGlobalSetting =
+                    Settings.Global.getString(resolver, Settings.Global.NTP_SERVER);
+            final List<URI> settingsServerUris = parseNtpServerSetting(serverGlobalSetting);
+
+            List<URI> ntpServerUris;
+            if (settingsServerUris != null) {
+                ntpServerUris = settingsServerUris;
+            } else {
+                String[] configValues =
+                        res.getStringArray(com.android.internal.R.array.config_ntpServers);
+                try {
+                    List<URI> configServerUris = new ArrayList<>();
+                    for (String configValue : configValues) {
+                        configServerUris.add(parseNtpUriStrict(configValue));
+                    }
+                    ntpServerUris = configServerUris;
+                } catch (URISyntaxException e) {
+                    ntpServerUris = null;
+                }
+            }
+
+            final int defaultTimeoutMillis =
+                    res.getInteger(com.android.internal.R.integer.config_ntpTimeout);
+            final Duration timeout = Duration.ofMillis(Settings.Global.getInt(
+                    resolver, Settings.Global.NTP_TIMEOUT, defaultTimeoutMillis));
+            return ntpServerUris == null ? null : new NtpConfig(ntpServerUris, timeout);
+        }
+
+        @Override
+        public Network getDefaultNetwork() {
+            ConnectivityManager connectivityManager = getConnectivityManager();
+            if (connectivityManager == null) {
+                return null;
+            }
+            return connectivityManager.getActiveNetwork();
+        }
+
+        @Override
+        public boolean isNetworkConnected(@NonNull Network network) {
+            ConnectivityManager connectivityManager = getConnectivityManager();
+            if (connectivityManager == null) {
+                return false;
+            }
+            final NetworkInfo ni = connectivityManager.getNetworkInfo(network);
+
+            // This connectivity check is to avoid performing a DNS lookup for the time server on a
+            // unconnected network. There are races to obtain time in Android when connectivity
+            // changes, which means that forceRefresh() can be called by various components before
+            // the network is actually available. This led in the past to DNS lookup failures being
+            // cached (~2 seconds) thereby preventing the device successfully making an NTP request
+            // when connectivity had actually been established.
+            // A side effect of check is that tests that run a fake NTP server on the device itself
+            // will only be able to use it if the active network is connected, even though loopback
+            // addresses are actually reachable.
+            if (ni == null || !ni.isConnected()) {
+                if (LOGD) Log.d(TAG, "getNetwork: no connectivity");
+                return false;
+            }
+            return true;
+        }
+
+        private synchronized ConnectivityManager getConnectivityManager() {
+            if (mConnectivityManager == null) {
+                mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
+            }
+            if (mConnectivityManager == null) {
+                if (LOGD) Log.d(TAG, "getConnectivityManager: no ConnectivityManager");
+            }
+            return mConnectivityManager;
+        }
+
+        @Override
+        @Nullable
+        public TimeResult queryNtpServer(
+                @NonNull Network network, @NonNull URI ntpServerUri, @NonNull Duration timeout) {
+
+            final SntpClient client = new SntpClient();
+            final String serverName = ntpServerUri.getHost();
+            final int port = ntpServerUri.getPort() == -1
+                    ? SntpClient.STANDARD_NTP_PORT : ntpServerUri.getPort();
+            final int timeoutMillis = saturatedCast(timeout.toMillis());
+            if (client.requestTime(serverName, port, timeoutMillis, network)) {
+                int ntpUncertaintyMillis = saturatedCast(client.getRoundTripTime() / 2);
+                InetSocketAddress ntpServerSocketAddress = client.getServerSocketAddress();
+                return new TimeResult(
+                        client.getNtpTime(), client.getNtpTimeReference(), ntpUncertaintyMillis,
+                        ntpServerSocketAddress);
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Casts a {@code long} to an {@code int}, clamping the value within the int range.
+         */
+        private static int saturatedCast(long longValue) {
+            if (longValue > Integer.MAX_VALUE) {
+                return Integer.MAX_VALUE;
+            }
+            if (longValue < Integer.MIN_VALUE) {
+                return Integer.MIN_VALUE;
+            }
+            return (int) longValue;
+        }
+    }
 }
diff --git a/core/java/android/util/SafetyProtectionUtils.java b/core/java/android/util/SafetyProtectionUtils.java
new file mode 100644
index 0000000..af985c5
--- /dev/null
+++ b/core/java/android/util/SafetyProtectionUtils.java
@@ -0,0 +1,53 @@
+/*
+ * 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.util;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.provider.DeviceConfig;
+
+/**
+ * Util class for whether we should show the safety protection resources.
+ *
+ * @hide
+ */
+public class SafetyProtectionUtils {
+    private static final String SAFETY_PROTECTION_RESOURCES_ENABLED = "safety_protection_enabled";
+
+    /**
+     * Determines whether we should show the safety protection resources.
+     * We show the resources only if
+     * (1) the feature flag safety_protection_enabled is enabled and
+     * (2) the config value config_safetyProtectionEnabled is enabled/true and
+     * (3) the resources exist (currently the resources only exist on GMS devices)
+     *
+     * TODO: make this an API in U
+     *
+     * @hide
+     */
+    public static boolean shouldShowSafetyProtectionResources(Context context) {
+        return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
+                SAFETY_PROTECTION_RESOURCES_ENABLED, false)
+                && context.getResources().getBoolean(
+                        Resources.getSystem()
+                                .getIdentifier("config_safetyProtectionEnabled",
+                                        "bool", "android"))
+                && context.getDrawable(android.R.drawable.ic_safety_protection) != null
+                && context.getString(android.R.string.safety_protection_display_text) != null
+                && !context.getString(android.R.string.safety_protection_display_text).isEmpty();
+    }
+}
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 6a0ec33..c198098 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -90,8 +90,10 @@
             ITYPE_IME,
             ITYPE_CLIMATE_BAR,
             ITYPE_EXTRA_NAVIGATION_BAR,
-            ITYPE_LOCAL_NAVIGATION_BAR_1,
-            ITYPE_LOCAL_NAVIGATION_BAR_2
+            ITYPE_LEFT_GENERIC_OVERLAY,
+            ITYPE_TOP_GENERIC_OVERLAY,
+            ITYPE_RIGHT_GENERIC_OVERLAY,
+            ITYPE_BOTTOM_GENERIC_OVERLAY
     })
     public @interface InternalInsetsType {}
 
@@ -135,10 +137,12 @@
     public static final int ITYPE_EXTRA_NAVIGATION_BAR = 21;
 
     /** Additional types for local insets. **/
-    public static final int ITYPE_LOCAL_NAVIGATION_BAR_1 = 22;
-    public static final int ITYPE_LOCAL_NAVIGATION_BAR_2 = 23;
+    public static final int ITYPE_LEFT_GENERIC_OVERLAY = 22;
+    public static final int ITYPE_TOP_GENERIC_OVERLAY = 23;
+    public static final int ITYPE_RIGHT_GENERIC_OVERLAY = 24;
+    public static final int ITYPE_BOTTOM_GENERIC_OVERLAY = 25;
 
-    static final int LAST_TYPE = ITYPE_LOCAL_NAVIGATION_BAR_2;
+    static final int LAST_TYPE = ITYPE_BOTTOM_GENERIC_OVERLAY;
     public static final int SIZE = LAST_TYPE + 1;
 
     // Derived types
@@ -698,8 +702,12 @@
         if ((types & Type.NAVIGATION_BARS) != 0) {
             result.add(ITYPE_NAVIGATION_BAR);
             result.add(ITYPE_EXTRA_NAVIGATION_BAR);
-            result.add(ITYPE_LOCAL_NAVIGATION_BAR_1);
-            result.add(ITYPE_LOCAL_NAVIGATION_BAR_2);
+        }
+        if ((types & Type.GENERIC_OVERLAYS) != 0) {
+            result.add(ITYPE_LEFT_GENERIC_OVERLAY);
+            result.add(ITYPE_TOP_GENERIC_OVERLAY);
+            result.add(ITYPE_RIGHT_GENERIC_OVERLAY);
+            result.add(ITYPE_BOTTOM_GENERIC_OVERLAY);
         }
         if ((types & Type.CAPTION_BAR) != 0) {
             result.add(ITYPE_CAPTION_BAR);
@@ -740,9 +748,12 @@
                 return Type.STATUS_BARS;
             case ITYPE_NAVIGATION_BAR:
             case ITYPE_EXTRA_NAVIGATION_BAR:
-            case ITYPE_LOCAL_NAVIGATION_BAR_1:
-            case ITYPE_LOCAL_NAVIGATION_BAR_2:
                 return Type.NAVIGATION_BARS;
+            case ITYPE_LEFT_GENERIC_OVERLAY:
+            case ITYPE_TOP_GENERIC_OVERLAY:
+            case ITYPE_RIGHT_GENERIC_OVERLAY:
+            case ITYPE_BOTTOM_GENERIC_OVERLAY:
+                return Type.GENERIC_OVERLAYS;
             case ITYPE_CAPTION_BAR:
                 return Type.CAPTION_BAR;
             case ITYPE_IME:
@@ -861,10 +872,14 @@
                 return "ITYPE_CLIMATE_BAR";
             case ITYPE_EXTRA_NAVIGATION_BAR:
                 return "ITYPE_EXTRA_NAVIGATION_BAR";
-            case ITYPE_LOCAL_NAVIGATION_BAR_1:
-                return "ITYPE_LOCAL_NAVIGATION_BAR_1";
-            case ITYPE_LOCAL_NAVIGATION_BAR_2:
-                return "ITYPE_LOCAL_NAVIGATION_BAR_2";
+            case ITYPE_LEFT_GENERIC_OVERLAY:
+                return "ITYPE_LEFT_GENERIC_OVERLAY";
+            case ITYPE_TOP_GENERIC_OVERLAY:
+                return "ITYPE_TOP_GENERIC_OVERLAY";
+            case ITYPE_RIGHT_GENERIC_OVERLAY:
+                return "ITYPE_RIGHT_GENERIC_OVERLAY";
+            case ITYPE_BOTTOM_GENERIC_OVERLAY:
+                return "ITYPE_BOTTOM_GENERIC_OVERLAY";
             default:
                 return "ITYPE_UNKNOWN_" + type;
         }
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..5f6c24b 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -233,7 +233,8 @@
     private static native boolean nativeGetProtectedContentSupport();
     private static native void nativeSetMetadata(long transactionObj, long nativeObject, int key,
             Parcel data);
-    private static native void nativeSyncInputWindows(long transactionObj);
+    private static native void nativeAddWindowInfosReportedListener(long transactionObj,
+            Runnable listener);
     private static native boolean nativeGetDisplayBrightnessSupport(IBinder displayToken);
     private static native boolean nativeSetDisplayBrightness(IBinder displayToken,
             float sdrBrightness, float sdrBrightnessNits, float displayBrightness,
@@ -249,6 +250,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,
@@ -3059,13 +3062,14 @@
         }
 
         /**
-         * Waits until any changes to input windows have been sent from SurfaceFlinger to
-         * InputFlinger before returning.
+         * Adds a callback that is called after WindowInfosListeners from the systems server are
+         * complete. This is primarily used to ensure that InputDispatcher::setInputWindowsLocked
+         * has been called before running the added callback.
          *
          * @hide
          */
-        public Transaction syncInputWindows() {
-            nativeSyncInputWindows(mNativeObject);
+        public Transaction addWindowInfosReportedListener(@NonNull Runnable listener) {
+            nativeAddWindowInfosReportedListener(mNativeObject, listener);
             return this;
         }
 
@@ -3614,6 +3618,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/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 536a0ac..c7dbc07 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -119,6 +119,10 @@
     final int[] mLocation = new int[2];
 
     @UnsupportedAppUsage
+    // Used to ensure the Surface remains valid between SurfaceHolder#lockCanvas and
+    // SurfaceHolder#unlockCanvasAndPost calls. This prevents SurfaceView from destroying or
+    // invalidating the Surface. This means this lock should be acquired when destroying the
+    // BlastBufferQueue.
     final ReentrantLock mSurfaceLock = new ReentrantLock();
     @UnsupportedAppUsage
     final Surface mSurface = new Surface();       // Current surface in use
@@ -724,14 +728,18 @@
 
     private void releaseSurfaces(boolean releaseSurfacePackage) {
         mSurfaceAlpha = 1f;
-        mSurface.destroy();
-
-        synchronized (mSurfaceControlLock) {
+        try {
+            mSurfaceLock.lock();
+            mSurface.destroy();
             if (mBlastBufferQueue != null) {
                 mBlastBufferQueue.destroy();
                 mBlastBufferQueue = null;
             }
+        } finally {
+            mSurfaceLock.unlock();
+        }
 
+        synchronized (mSurfaceControlLock) {
             final Transaction transaction = new Transaction();
             if (mSurfaceControl != null) {
                 transaction.remove(mSurfaceControl);
@@ -1232,16 +1240,21 @@
                     .build();
         }
 
-        // Always recreate the IGBP for compatibility. This can be optimized in the future but
-        // the behavior change will need to be gated by SDK version.
-        if (mBlastBufferQueue != null) {
-            mBlastBufferQueue.destroy();
-        }
         mTransformHint = viewRoot.getBufferTransformHint();
         mBlastSurfaceControl.setTransformHint(mTransformHint);
 
-        mBlastBufferQueue = new BLASTBufferQueue(name, false /* updateDestinationFrame */);
-        mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat);
+        // Always recreate the IGBP for compatibility. This can be optimized in the future but
+        // the behavior change will need to be gated by SDK version.
+        try {
+            mSurfaceLock.lock();
+            if (mBlastBufferQueue != null) {
+                mBlastBufferQueue.destroy();
+            }
+            mBlastBufferQueue = new BLASTBufferQueue(name, false /* updateDestinationFrame */);
+            mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat);
+        } finally {
+            mSurfaceLock.unlock();
+        }
         mBlastBufferQueue.setTransactionHangCallback(ViewRootImpl.sTransactionHangCallback);
     }
 
@@ -1814,7 +1827,14 @@
             // so the next connect will always work if we end up reusing
             // the surface.
             if (mSurface.isValid()) {
-                mSurface.forceScopedDisconnect();
+                // We need to grab this lock since mSurface.forceScopedDisconnect
+                // will free buffers from the queue.
+                try {
+                    mSurfaceLock.lock();
+                    mSurface.forceScopedDisconnect();
+                } finally {
+                    mSurfaceLock.unlock();
+                }
             }
         }
     }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1e9769e..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...
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index bcaa1b2..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();
         }
     }
 
@@ -3024,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()
@@ -3064,7 +3084,6 @@
                 if (surfaceReplaced) {
                     mSurfaceSequenceId++;
                 }
-
                 if (alwaysConsumeSystemBarsChanged) {
                     mAttachInfo.mAlwaysConsumeSystemBars = mPendingAlwaysConsumeSystemBars;
                     dispatchApplyInsets = true;
@@ -3763,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
@@ -10289,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 ed8350a..2c077c3 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -109,8 +109,6 @@
     /**
      * Interface definition for a callback to be invoked when the view hierarchy's window
      * visibility changes.
-     *
-     * @hide
      */
     public interface OnWindowVisibilityChangeListener {
         /**
@@ -569,8 +567,6 @@
      * @param listener The callback to add
      *
      * @throws IllegalStateException If {@link #isAlive()} returns false
-     *
-     * @hide
      */
     public void addOnWindowVisibilityChangeListener(
             @NonNull OnWindowVisibilityChangeListener listener) {
@@ -593,8 +589,6 @@
      *
      * @see #addOnWindowVisibilityChangeListener(
      * android.view.ViewTreeObserver.OnWindowVisibilityChangeListener)
-     *
-     * @hide
      */
     public void removeOnWindowVisibilityChangeListener(
             @NonNull OnWindowVisibilityChangeListener victim) {
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index c846175..c1dddbe 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -1423,9 +1423,11 @@
 
         static final int DISPLAY_CUTOUT = 1 << 7;
 
-        static final int LAST = 1 << 8;
-        static final int SIZE = 9;
-        static final int WINDOW_DECOR = LAST;
+        static final int WINDOW_DECOR = 1 << 8;
+
+        static final int GENERIC_OVERLAYS = 1 << 9;
+        static final int LAST = GENERIC_OVERLAYS;
+        static final int SIZE = 10;
 
         static int indexOf(@InsetsType int type) {
             switch (type) {
@@ -1447,6 +1449,8 @@
                     return 7;
                 case WINDOW_DECOR:
                     return 8;
+                case GENERIC_OVERLAYS:
+                    return 9;
                 default:
                     throw new IllegalArgumentException("type needs to be >= FIRST and <= LAST,"
                             + " type=" + type);
@@ -1482,6 +1486,9 @@
             if ((types & WINDOW_DECOR) != 0) {
                 result.append("windowDecor |");
             }
+            if ((types & GENERIC_OVERLAYS) != 0) {
+                result.append("genericOverlays |");
+            }
             if (result.length() > 0) {
                 result.delete(result.length() - 2, result.length());
             }
@@ -1494,7 +1501,8 @@
         /** @hide */
         @Retention(RetentionPolicy.SOURCE)
         @IntDef(flag = true, value = {STATUS_BARS, NAVIGATION_BARS, CAPTION_BAR, IME, WINDOW_DECOR,
-                SYSTEM_GESTURES, MANDATORY_SYSTEM_GESTURES, TAPPABLE_ELEMENT, DISPLAY_CUTOUT})
+                SYSTEM_GESTURES, MANDATORY_SYSTEM_GESTURES, TAPPABLE_ELEMENT, DISPLAY_CUTOUT,
+                GENERIC_OVERLAYS})
         public @interface InsetsType {
         }
 
@@ -1586,7 +1594,7 @@
          *         {@link #navigationBars()}, but not {@link #ime()}.
          */
         public static @InsetsType int systemBars() {
-            return STATUS_BARS | NAVIGATION_BARS | CAPTION_BAR;
+            return STATUS_BARS | NAVIGATION_BARS | CAPTION_BAR | GENERIC_OVERLAYS;
         }
 
         /**
diff --git a/core/java/android/view/WindowLayout.java b/core/java/android/view/WindowLayout.java
index 0941ee8..57a0330 100644
--- a/core/java/android/view/WindowLayout.java
+++ b/core/java/android/view/WindowLayout.java
@@ -274,7 +274,7 @@
         }
 
         if (extendedByCutout) {
-            extendFrameByCutout(attrs.gravity, displayCutoutSafe, outDisplayFrame, outFrame,
+            extendFrameByCutout(displayCutoutSafe, outDisplayFrame, outFrame,
                     mTempRect);
         }
 
@@ -291,7 +291,7 @@
                 + " requestedVisibilities=" + requestedVisibilities);
     }
 
-    public static void extendFrameByCutout(int gravity, Rect displayCutoutSafe,
+    public static void extendFrameByCutout(Rect displayCutoutSafe,
             Rect displayFrame, Rect inOutFrame, Rect tempRect) {
         if (displayCutoutSafe.contains(inOutFrame)) {
             return;
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 13ea7af..70a690c 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.
@@ -2374,6 +2401,14 @@
         public static final int SYSTEM_FLAG_SHOW_FOR_ALL_USERS = 0x00000010;
 
         /**
+         * Flag to allow this window to have unrestricted gesture exclusion.
+         *
+         * @see View#setSystemGestureExclusionRects(List)
+         * @hide
+         */
+        public static final int PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION = 0x00000020;
+
+        /**
          * Never animate position changes of the window.
          *
          * {@hide}
@@ -2593,6 +2628,7 @@
                 PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED,
                 PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS,
                 SYSTEM_FLAG_SHOW_FOR_ALL_USERS,
+                PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION,
                 PRIVATE_FLAG_NO_MOVE_ANIMATION,
                 PRIVATE_FLAG_COMPATIBLE_WINDOW,
                 PRIVATE_FLAG_SYSTEM_ERROR,
@@ -2640,6 +2676,10 @@
                         equals = SYSTEM_FLAG_SHOW_FOR_ALL_USERS,
                         name = "SHOW_FOR_ALL_USERS"),
                 @ViewDebug.FlagToString(
+                        mask = PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION,
+                        equals = PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION,
+                        name = "UNRESTRICTED_GESTURE_EXCLUSION"),
+                @ViewDebug.FlagToString(
                         mask = PRIVATE_FLAG_NO_MOVE_ANIMATION,
                         equals = PRIVATE_FLAG_NO_MOVE_ANIMATION,
                         name = "NO_MOVE_ANIMATION"),
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/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/app/timedetector/GnssTimeSuggestion.aidl b/core/java/android/view/accessibility/AccessibilityWindowAttributes.aidl
similarity index 72%
copy from core/java/android/app/timedetector/GnssTimeSuggestion.aidl
copy to core/java/android/view/accessibility/AccessibilityWindowAttributes.aidl
index 81475ec..0917458 100644
--- a/core/java/android/app/timedetector/GnssTimeSuggestion.aidl
+++ b/core/java/android/view/accessibility/AccessibilityWindowAttributes.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2020 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.
  * 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,
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.app.timedetector;
+package android.view.accessibility;
 
-parcelable GnssTimeSuggestion;
+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/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index 98ef4e7..90384b5 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -64,6 +64,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.NoSuchElementException;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
@@ -630,7 +631,11 @@
         mComponentName = null;
         mEvents = null;
         if (mDirectServiceInterface != null) {
-            mDirectServiceInterface.asBinder().unlinkToDeath(mDirectServiceVulture, 0);
+            try {
+                mDirectServiceInterface.asBinder().unlinkToDeath(mDirectServiceVulture, 0);
+            } catch (NoSuchElementException e) {
+                Log.w(TAG, "IContentCaptureDirectManager does not exist");
+            }
         }
         mDirectServiceInterface = null;
         mHandler.removeMessages(MSG_FLUSH);
diff --git a/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java b/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java
index 4b472ed..8dbaec4 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,28 +88,31 @@
     }
 
     @AnyThread
-    List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String imiId,
-            boolean allowsImplicitlySelectedSubtypes) {
+    @NonNull
+    List<InputMethodSubtype> getEnabledInputMethodSubtypeList(@Nullable String imiId,
+            boolean allowsImplicitlySelectedSubtypes, @UserIdInt int userId) {
         try {
             return mTarget.getEnabledInputMethodSubtypeList(imiId,
-                    allowsImplicitlySelectedSubtypes);
+                    allowsImplicitlySelectedSubtypes, userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
     @AnyThread
-    InputMethodSubtype getLastInputMethodSubtype() {
+    @Nullable
+    InputMethodSubtype getLastInputMethodSubtype(@UserIdInt int userId) {
         try {
-            return mTarget.getLastInputMethodSubtype();
+            return mTarget.getLastInputMethodSubtype(userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
     @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 1b14110..adeed25 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();
@@ -1017,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;
                         }
@@ -1101,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) {
@@ -1146,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
@@ -1400,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);
     }
 
     /**
@@ -1452,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);
     }
 
     /**
@@ -1468,7 +1468,7 @@
     @NonNull
     public List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId,
             @DirectBootAwareness int directBootAwareness) {
-        return mServiceInvoker.getAwareLockedInputMethodList(userId, directBootAwareness);
+        return mServiceInvoker.getInputMethodList(userId, directBootAwareness);
     }
 
     /**
@@ -1478,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
@@ -1502,16 +1503,19 @@
      *
      * <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(),
-                allowsImplicitlySelectedSubtypes);
+                allowsImplicitlySelectedSubtypes,
+                UserHandle.myUserId());
     }
 
     /**
@@ -1624,14 +1628,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;
     }
 
@@ -1639,47 +1642,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();
@@ -2229,7 +2242,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;
@@ -2389,8 +2402,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();
@@ -2443,6 +2455,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.
      *
@@ -2591,7 +2614,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);
         }
@@ -3060,7 +3083,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);
@@ -3075,7 +3098,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());
@@ -3100,7 +3123,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);
@@ -3124,7 +3147,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
@@ -3223,8 +3246,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);
     }
 
     /**
@@ -3232,6 +3274,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();
     }
@@ -3278,7 +3321,8 @@
             return false;
         }
         final List<InputMethodSubtype> enabledSubtypes =
-                mServiceInvoker.getEnabledInputMethodSubtypeList(imeId, true);
+                mServiceInvoker.getEnabledInputMethodSubtypeList(imeId, true,
+                        UserHandle.myUserId());
         final int numSubtypes = enabledSubtypes.size();
         for (int i = 0; i < numSubtypes; ++i) {
             final InputMethodSubtype enabledSubtype = enabledSubtypes.get(i);
@@ -3466,12 +3510,14 @@
      *             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();
+        return mServiceInvoker.getLastInputMethodSubtype(UserHandle.myUserId());
     }
 
     /**
@@ -3484,7 +3530,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;
         }
@@ -3494,7 +3540,7 @@
         p.println("  mFallbackInputConnection=" + mFallbackInputConnection);
         p.println("  mActive=" + mActive
                 + " mRestartOnNextWindowFocus=" + mRestartOnNextWindowFocus
-                + " mBindSequence=" + mBindSequence
+                + " mBindSequence=" + getBindSequenceLocked()
                 + " mCurImeId=" + getImeIdLocked());
         p.println("  mFullscreenMode=" + mFullscreenMode);
         if (isImeSessionAvailableLocked()) {
@@ -3593,11 +3639,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;
         }
     }
 
@@ -3611,6 +3663,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/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/widget/Toast.java b/core/java/android/widget/Toast.java
index dbf3570..ca57c84 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -32,6 +32,7 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Handler;
@@ -494,19 +495,39 @@
      */
     public static Toast makeText(@NonNull Context context, @Nullable Looper looper,
             @NonNull CharSequence text, @Duration int duration) {
-        if (Compatibility.isChangeEnabled(CHANGE_TEXT_TOASTS_IN_THE_SYSTEM)) {
-            Toast result = new Toast(context, looper);
-            result.mText = text;
-            result.mDuration = duration;
-            return result;
-        } else {
-            Toast result = new Toast(context, looper);
-            View v = ToastPresenter.getTextToastView(context, text);
-            result.mNextView = v;
-            result.mDuration = duration;
+        Toast result = new Toast(context, looper);
 
-            return result;
+        if (Compatibility.isChangeEnabled(CHANGE_TEXT_TOASTS_IN_THE_SYSTEM)) {
+            result.mText = text;
+        } else {
+            result.mNextView = ToastPresenter.getTextToastView(context, text);
         }
+
+        result.mDuration = duration;
+        return result;
+    }
+
+    /**
+     * Make a standard toast with an icon to display using the specified looper.
+     * If looper is null, Looper.myLooper() is used.
+     *
+     * The toast will be a custom view that's rendered by the app (instead of by SystemUI).
+     * In Android version R and above, non-system apps can only render the toast
+     * when it's in the foreground.
+     *
+     * @hide
+     */
+    public static Toast makeCustomToastWithIcon(@NonNull Context context, @Nullable Looper looper,
+            @NonNull CharSequence text, @Duration int duration, @NonNull Drawable icon) {
+        if (icon == null) {
+            throw new IllegalArgumentException("Drawable icon should not be null "
+                    + "for makeCustomToastWithIcon");
+        }
+
+        Toast result = new Toast(context, looper);
+        result.mNextView = ToastPresenter.getTextToastViewWithIcon(context, text, icon);
+        result.mDuration = duration;
+        return result;
     }
 
     /**
diff --git a/core/java/android/widget/ToastPresenter.java b/core/java/android/widget/ToastPresenter.java
index eccff06..7467100 100644
--- a/core/java/android/widget/ToastPresenter.java
+++ b/core/java/android/widget/ToastPresenter.java
@@ -25,6 +25,7 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Log;
@@ -55,6 +56,8 @@
 
     @VisibleForTesting
     public static final int TEXT_TOAST_LAYOUT = R.layout.transient_notification;
+    @VisibleForTesting
+    public static final int TEXT_TOAST_LAYOUT_WITH_ICON = R.layout.transient_notification_with_icon;
 
     /**
      * Returns the default text toast view for message {@code text}.
@@ -66,6 +69,24 @@
         return view;
     }
 
+    /**
+     * Returns the default icon text toast view for message {@code text} and the icon {@code icon}.
+     */
+    public static View getTextToastViewWithIcon(Context context, CharSequence text, Drawable icon) {
+        if (icon == null) {
+            return getTextToastView(context, text);
+        }
+
+        View view = LayoutInflater.from(context).inflate(TEXT_TOAST_LAYOUT_WITH_ICON, null);
+        TextView textView = view.findViewById(com.android.internal.R.id.message);
+        textView.setText(text);
+        ImageView imageView = view.findViewById(com.android.internal.R.id.icon);
+        if (imageView != null) {
+            imageView.setImageDrawable(icon);
+        }
+        return view;
+    }
+
     private final Context mContext;
     private final Resources mResources;
     private final WindowManager mWindowManager;
diff --git a/core/java/android/window/ITaskFragmentOrganizer.aidl b/core/java/android/window/ITaskFragmentOrganizer.aidl
index 8dfda7d..3335c9c 100644
--- a/core/java/android/window/ITaskFragmentOrganizer.aidl
+++ b/core/java/android/window/ITaskFragmentOrganizer.aidl
@@ -45,10 +45,11 @@
      *
      * @param errorCallbackToken    Token set through {@link
      *                              WindowContainerTransaction#setErrorCallbackToken(IBinder)}
-     * @param exceptionBundle   Bundle containing the exception. Should be created with
-     *                          {@link TaskFragmentOrganizer#putExceptionInBundle}.
+     * @param errorBundle       Bundle containing the exception, operation type and TaskFragmentInfo
+     *                          if any. Should be created with
+     *                          {@link TaskFragmentOrganizer#putErrorInfoInBundle}.
      */
-    void onTaskFragmentError(in IBinder errorCallbackToken, in Bundle exceptionBundle);
+    void onTaskFragmentError(in IBinder errorCallbackToken, in Bundle errorBundle);
 
     /**
      * Called when an Activity is reparented to the Task with organized TaskFragment. For example,
diff --git a/core/java/android/window/ImeOnBackInvokedDispatcher.java b/core/java/android/window/ImeOnBackInvokedDispatcher.java
index 5924844..2fc22c2 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());
@@ -219,8 +221,6 @@
      * @param previous the previously focused {@link ViewRootImpl}.
      * @param current the currently focused {@link ViewRootImpl}.
      */
-    // TODO(b/232845902): Add CTS to test IME back behavior when there's root view change while
-    // IME is up.
     public void switchRootView(ViewRootImpl previous, ViewRootImpl current) {
         for (ImeOnBackInvokedCallback imeCallback : mImeCallbacks) {
             if (previous != null) {
diff --git a/core/java/android/window/TaskFragmentOrganizer.java b/core/java/android/window/TaskFragmentOrganizer.java
index 68c934f..765cd81 100644
--- a/core/java/android/window/TaskFragmentOrganizer.java
+++ b/core/java/android/window/TaskFragmentOrganizer.java
@@ -18,6 +18,7 @@
 
 import android.annotation.CallSuper;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.content.Intent;
 import android.content.res.Configuration;
@@ -39,16 +40,23 @@
      * Key to the exception in {@link Bundle} in {@link ITaskFragmentOrganizer#onTaskFragmentError}.
      */
     private static final String KEY_ERROR_CALLBACK_EXCEPTION = "fragment_exception";
+    private static final String KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO = "task_fragment_info";
+    private static final String KEY_ERROR_CALLBACK_OP_TYPE = "operation_type";
 
     /**
-     * Creates a {@link Bundle} with an exception that can be passed to
-     * {@link ITaskFragmentOrganizer#onTaskFragmentError}.
+     * Creates a {@link Bundle} with an exception, operation type and TaskFragmentInfo (if any)
+     * that can be passed to {@link ITaskFragmentOrganizer#onTaskFragmentError}.
      * @hide
      */
-    public static Bundle putExceptionInBundle(@NonNull Throwable exception) {
-        final Bundle exceptionBundle = new Bundle();
-        exceptionBundle.putSerializable(KEY_ERROR_CALLBACK_EXCEPTION, exception);
-        return exceptionBundle;
+    public static @NonNull Bundle putErrorInfoInBundle(@NonNull Throwable exception,
+            @Nullable TaskFragmentInfo info, int opType) {
+        final Bundle errorBundle = new Bundle();
+        errorBundle.putSerializable(KEY_ERROR_CALLBACK_EXCEPTION, exception);
+        if (info != null) {
+            errorBundle.putParcelable(KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO, info);
+        }
+        errorBundle.putInt(KEY_ERROR_CALLBACK_OP_TYPE, opType);
+        return errorBundle;
     }
 
     /**
@@ -150,10 +158,15 @@
      *
      * @param errorCallbackToken    token set in
      *                             {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)}
+     * @param taskFragmentInfo  The {@link TaskFragmentInfo}. This could be {@code null} if no
+     *                          TaskFragment created.
+     * @param opType            The {@link WindowContainerTransaction.HierarchyOp} of the failed
+     *                          transaction operation.
      * @param exception             exception from the server side.
      */
     public void onTaskFragmentError(
-            @NonNull IBinder errorCallbackToken, @NonNull Throwable exception) {}
+            @NonNull IBinder errorCallbackToken, @Nullable TaskFragmentInfo taskFragmentInfo,
+            int opType, @NonNull Throwable exception) {}
 
     /**
      * Called when an Activity is reparented to the Task with organized TaskFragment. For example,
@@ -217,10 +230,16 @@
 
         @Override
         public void onTaskFragmentError(
-                @NonNull IBinder errorCallbackToken, @NonNull Bundle exceptionBundle) {
-            mExecutor.execute(() -> TaskFragmentOrganizer.this.onTaskFragmentError(
-                    errorCallbackToken,
-                    (Throwable) exceptionBundle.getSerializable(KEY_ERROR_CALLBACK_EXCEPTION, java.lang.Throwable.class)));
+                @NonNull IBinder errorCallbackToken, @NonNull Bundle errorBundle) {
+            mExecutor.execute(() -> {
+                final TaskFragmentInfo info = errorBundle.getParcelable(
+                        KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO, TaskFragmentInfo.class);
+                TaskFragmentOrganizer.this.onTaskFragmentError(
+                        errorCallbackToken, info,
+                        errorBundle.getInt(KEY_ERROR_CALLBACK_OP_TYPE),
+                        (Throwable) errorBundle.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/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/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index 737d5e3..b32afb4 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -417,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;
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 100fcd8..01dcf962 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -136,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/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/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/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..1b77147 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -38,25 +38,26 @@
     // 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,
-            boolean allowsImplicitlySelectedSubtypes);
-    InputMethodSubtype getLastInputMethodSubtype();
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+            + "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)")
+    List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in @nullable String imiId,
+            boolean allowsImplicitlySelectedSubtypes, int userId);
 
-    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);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+            + "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)")
+    InputMethodSubtype getLastInputMethodSubtype(int userId);
+
+    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 +66,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 +120,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/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 17a47d3..cc076ab 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
@@ -179,9 +170,7 @@
     public static final String PROFILE_KEY_NAME_DECRYPT = "profile_key_name_decrypt_";
     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 CURRENT_LSKF_BASED_PROTECTOR_ID_KEY = "sp-handle";
     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/LockscreenCredential.java b/core/java/com/android/internal/widget/LockscreenCredential.java
index 1074004..40164a4 100644
--- a/core/java/com/android/internal/widget/LockscreenCredential.java
+++ b/core/java/com/android/internal/widget/LockscreenCredential.java
@@ -40,8 +40,8 @@
 import java.util.Objects;
 
 /**
- * A class representing a lockscreen credential. It can be either an empty password, a pattern
- * or a password (or PIN).
+ * A class representing a lockscreen credential, also called a Lock Screen Knowledge Factor (LSKF).
+ * It can be a PIN, pattern, password, or none (a.k.a. empty).
  *
  * <p> As required by some security certification, the framework tries its best to
  * remove copies of the lockscreen credential bytes from memory. In this regard, this class
@@ -52,10 +52,10 @@
  *     // Process the credential in some way
  * }
  * </pre>
- * With this construct, we can guarantee that there will be no copies of the password left in
- * memory when the credential goes out of scope. This should help mitigate certain class of
- * attacks where the attcker gains read-only access to full device memory (cold boot attack,
- * unsecured software/hardware memory dumping interfaces such as JTAG).
+ * With this construct, we can guarantee that there will be no copies of the credential left in
+ * memory when the object goes out of scope. This should help mitigate certain class of attacks
+ * where the attacker gains read-only access to full device memory (cold boot attack, unsecured
+ * software/hardware memory dumping interfaces such as JTAG).
  */
 public class LockscreenCredential implements Parcelable, AutoCloseable {
 
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index aa66171..4bc946e 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -50,6 +50,7 @@
         "android_util_XmlBlock.cpp",
         "android_util_jar_StrictJarFile.cpp",
         "com_android_internal_util_VirtualRefBasePtr.cpp",
+        "core_jni_helpers.cpp",
         ":deviceproductinfoconstants_aidl",
     ],
 
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_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index 78b403c..cb97698 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -348,7 +348,7 @@
     virtual int handleEvent(int fd, int events, void* data) {
         JNIEnv* env = AndroidRuntime::getJNIEnv();
         sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data);
-        ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
+        ScopedLocalRef<jobject> receiverObj(env, GetReferent(env, mReceiverWeakGlobal));
 
         ssize_t n;
         ASensorEvent buffer[16];
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_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp
index c9110d1..019e3bd 100644
--- a/core/jni/android_view_DisplayEventReceiver.cpp
+++ b/core/jni/android_view_DisplayEventReceiver.cpp
@@ -139,7 +139,7 @@
                                                uint32_t count, VsyncEventData vsyncEventData) {
     JNIEnv* env = AndroidRuntime::getJNIEnv();
 
-    ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
+    ScopedLocalRef<jobject> receiverObj(env, GetReferent(env, mReceiverWeakGlobal));
     if (receiverObj.get()) {
         ALOGV("receiver %p ~ Invoking vsync handler.", this);
 
@@ -156,7 +156,7 @@
                                                  bool connected) {
     JNIEnv* env = AndroidRuntime::getJNIEnv();
 
-    ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
+    ScopedLocalRef<jobject> receiverObj(env, GetReferent(env, mReceiverWeakGlobal));
     if (receiverObj.get()) {
         ALOGV("receiver %p ~ Invoking hotplug handler.", this);
         env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchHotplug,
@@ -171,7 +171,7 @@
                                                      int32_t modeId, nsecs_t) {
     JNIEnv* env = AndroidRuntime::getJNIEnv();
 
-    ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
+    ScopedLocalRef<jobject> receiverObj(env, GetReferent(env, mReceiverWeakGlobal));
     if (receiverObj.get()) {
         ALOGV("receiver %p ~ Invoking mode changed handler.", this);
         env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchModeChanged,
@@ -186,7 +186,7 @@
         nsecs_t timestamp, PhysicalDisplayId displayId, std::vector<FrameRateOverride> overrides) {
     JNIEnv* env = AndroidRuntime::getJNIEnv();
 
-    ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
+    ScopedLocalRef<jobject> receiverObj(env, GetReferent(env, mReceiverWeakGlobal));
     if (receiverObj.get()) {
         ALOGV("receiver %p ~ Invoking FrameRateOverride handler.", this);
         const auto frameRateOverrideClass =
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index a7ec38f..2b932cb 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -329,7 +329,7 @@
             if (!skipCallbacks && !mBatchedInputEventPending && mInputConsumer.hasPendingBatch()) {
                 // There is a pending batch.  Come back later.
                 if (!receiverObj.get()) {
-                    receiverObj.reset(jniGetReferent(env, mReceiverWeakGlobal));
+                    receiverObj.reset(GetReferent(env, mReceiverWeakGlobal));
                     if (!receiverObj.get()) {
                         ALOGW("channel '%s' ~ Receiver object was finalized "
                               "without being disposed.",
@@ -358,7 +358,7 @@
 
         if (!skipCallbacks) {
             if (!receiverObj.get()) {
-                receiverObj.reset(jniGetReferent(env, mReceiverWeakGlobal));
+                receiverObj.reset(GetReferent(env, mReceiverWeakGlobal));
                 if (!receiverObj.get()) {
                     ALOGW("channel '%s' ~ Receiver object was finalized "
                             "without being disposed.", getInputChannelName().c_str());
diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp
index 5da2738..4bc567a 100644
--- a/core/jni/android_view_InputEventSender.cpp
+++ b/core/jni/android_view_InputEventSender.cpp
@@ -200,7 +200,7 @@
         ALOGD("channel '%s' ~ Receiving finished signals.", getInputChannelName().c_str());
     }
 
-    ScopedLocalRef<jobject> senderObj(env, jniGetReferent(env, mSenderWeakGlobal));
+    ScopedLocalRef<jobject> senderObj(env, GetReferent(env, mSenderWeakGlobal));
     if (!senderObj.get()) {
         ALOGW("channel '%s' ~ Sender object was finalized without being disposed.",
               getInputChannelName().c_str());
diff --git a/core/jni/android_view_InputQueue.cpp b/core/jni/android_view_InputQueue.cpp
index 74bbd7b..2f9df1f 100644
--- a/core/jni/android_view_InputQueue.cpp
+++ b/core/jni/android_view_InputQueue.cpp
@@ -136,7 +136,7 @@
     switch(message.what) {
     case MSG_FINISH_INPUT:
         JNIEnv* env = AndroidRuntime::getJNIEnv();
-        ScopedLocalRef<jobject> inputQueueObj(env, jniGetReferent(env, mInputQueueWeakGlobal));
+        ScopedLocalRef<jobject> inputQueueObj(env, GetReferent(env, mInputQueueWeakGlobal));
         if (!inputQueueObj.get()) {
             ALOGW("InputQueue was finalized without being disposed");
             return;
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index f89298a..22f84b6 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -17,18 +17,12 @@
 #define LOG_TAG "SurfaceControl"
 #define LOG_NDEBUG 0
 
-#include "android_os_Parcel.h"
-#include "android_util_Binder.h"
-#include "android_hardware_input_InputWindowHandle.h"
-#include "core_jni_helpers.h"
-
-#include <memory>
-
 #include <aidl/android/hardware/graphics/common/PixelFormat.h>
 #include <android-base/chrono_utils.h>
 #include <android/graphics/properties.h>
 #include <android/graphics/region.h>
 #include <android/gui/BnScreenCaptureListener.h>
+#include <android/gui/BnWindowInfosReportedListener.h>
 #include <android/hardware/display/IDeviceProductInfoConstants.h>
 #include <android/os/IInputConstants.h>
 #include <android_runtime/AndroidRuntime.h>
@@ -60,6 +54,13 @@
 #include <utils/LightRefBase.h>
 #include <utils/Log.h>
 
+#include <memory>
+
+#include "android_hardware_input_InputWindowHandle.h"
+#include "android_os_Parcel.h"
+#include "android_util_Binder.h"
+#include "core_jni_helpers.h"
+
 // ----------------------------------------------------------------------------
 
 namespace android {
@@ -89,6 +90,11 @@
 
 static struct {
     jclass clazz;
+    jmethodID run;
+} gRunnableClassInfo;
+
+static struct {
+    jclass clazz;
     jmethodID ctor;
     jfieldID isInternal;
     jfieldID density;
@@ -381,6 +387,38 @@
     }
 };
 
+class WindowInfosReportedListenerWrapper : public gui::BnWindowInfosReportedListener {
+public:
+    explicit WindowInfosReportedListenerWrapper(JNIEnv* env, jobject listener) {
+        env->GetJavaVM(&mVm);
+        mListener = env->NewGlobalRef(listener);
+        LOG_ALWAYS_FATAL_IF(!mListener, "Failed to make global ref");
+    }
+
+    ~WindowInfosReportedListenerWrapper() {
+        if (mListener) {
+            getenv()->DeleteGlobalRef(mListener);
+            mListener = nullptr;
+        }
+    }
+
+    binder::Status onWindowInfosReported() override {
+        JNIEnv* env = getenv();
+        env->CallVoidMethod(mListener, gRunnableClassInfo.run);
+        return binder::Status::ok();
+    }
+
+private:
+    jobject mListener;
+    JavaVM* mVm;
+
+    JNIEnv* getenv() {
+        JNIEnv* env;
+        mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
+        return env;
+    }
+};
+
 // ----------------------------------------------------------------------------
 
 static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) {
@@ -890,9 +928,11 @@
     transaction->setInputWindowInfo(ctrl, *handle->getInfo());
 }
 
-static void nativeSyncInputWindows(JNIEnv* env, jclass clazz, jlong transactionObj) {
+static void nativeAddWindowInfosReportedListener(JNIEnv* env, jclass clazz, jlong transactionObj,
+                                                 jobject runnable) {
+    auto listener = sp<WindowInfosReportedListenerWrapper>::make(env, runnable);
     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
-    transaction->syncInputWindows();
+    transaction->addWindowInfosReportedListener(listener);
 }
 
 static void nativeSetMetadata(JNIEnv* env, jclass clazz, jlong transactionObj,
@@ -1018,6 +1058,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 +2206,8 @@
             (void*)nativeSetShadowRadius },
     {"nativeSetFrameRate", "(JJFII)V",
             (void*)nativeSetFrameRate },
+    {"nativeSetDefaultFrameRateCompatibility", "(JJI)V",
+            (void*)nativeSetDefaultFrameRateCompatibility},
     {"nativeGetPhysicalDisplayIds", "()[J",
             (void*)nativeGetPhysicalDisplayIds },
     {"nativeGetPrimaryPhysicalDisplayId", "()J",
@@ -2247,8 +2298,8 @@
     {"nativeSetBufferTransform", "(JJI)V", (void*) nativeSetBufferTransform},
     {"nativeSetDataSpace", "(JJI)V",
             (void*)nativeSetDataSpace },
-    {"nativeSyncInputWindows", "(J)V",
-            (void*)nativeSyncInputWindows },
+    {"nativeAddWindowInfosReportedListener", "(JLjava/lang/Runnable;)V",
+            (void*)nativeAddWindowInfosReportedListener },
     {"nativeGetDisplayBrightnessSupport", "(Landroid/os/IBinder;)Z",
             (void*)nativeGetDisplayBrightnessSupport },
     {"nativeSetDisplayBrightness", "(Landroid/os/IBinder;FFFF)Z",
@@ -2312,6 +2363,10 @@
     gIntegerClassInfo.clazz = MakeGlobalRefOrDie(env, integerClass);
     gIntegerClassInfo.ctor = GetMethodIDOrDie(env, gIntegerClassInfo.clazz, "<init>", "(I)V");
 
+    jclass runnableClazz = FindClassOrDie(env, "java/lang/Runnable");
+    gRunnableClassInfo.clazz = MakeGlobalRefOrDie(env, runnableClazz);
+    gRunnableClassInfo.run = GetMethodIDOrDie(env, runnableClazz, "run", "()V");
+
     jclass infoClazz = FindClassOrDie(env, "android/view/SurfaceControl$StaticDisplayInfo");
     gStaticDisplayInfoClassInfo.clazz = MakeGlobalRefOrDie(env, infoClazz);
     gStaticDisplayInfoClassInfo.ctor = GetMethodIDOrDie(env, infoClazz, "<init>", "()V");
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/jni/core_jni_helpers.cpp b/core/jni/core_jni_helpers.cpp
new file mode 100644
index 0000000..b65053b
--- /dev/null
+++ b/core/jni/core_jni_helpers.cpp
@@ -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.
+ */
+
+#include "core_jni_helpers.h"
+
+namespace android {
+
+namespace {
+
+jmethodID gGetReferent = nullptr;
+
+} // namespace
+
+jobject GetReferent(JNIEnv* env, jobject ref) {
+    if (gGetReferent == nullptr) {
+        jclass clazz = FindClassOrDie(env, "java/lang/ref/Reference");
+        gGetReferent = GetMethodIDOrDie(env, clazz, "get", "()Ljava/lang/Object;");
+    }
+    return env->CallObjectMethod(ref, gGetReferent);
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/core/jni/core_jni_helpers.h b/core/jni/core_jni_helpers.h
index 5268049..b85a425 100644
--- a/core/jni/core_jni_helpers.h
+++ b/core/jni/core_jni_helpers.h
@@ -90,11 +90,10 @@
     return res;
 }
 
-static inline jobject jniGetReferent(JNIEnv* env, jobject ref) {
-    jclass cls = FindClassOrDie(env, "java/lang/ref/Reference");
-    jmethodID get = GetMethodIDOrDie(env, cls, "get", "()Ljava/lang/Object;");
-    return env->CallObjectMethod(ref, get);
-}
+/**
+ * Returns the result of invoking java.lang.ref.Reference.get() on a Reference object.
+ */
+jobject GetReferent(JNIEnv* env, jobject ref);
 
 /**
  * Read the specified field from jobject, and convert to std::string.
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 6a421f0..285258a 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -473,6 +473,13 @@
     }
     optional PowerMenuPrivacy power_menu_privacy = 81;
 
+    message ExtraLowPowerMode {
+        option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+        optional SettingProto extra_automatic_power_save_mode = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+    }
+    optional ExtraLowPowerMode extra_low_power_mode = 93;
+
     message PrintService {
         option (android.msg_privacy).dest = DEST_EXPLICIT;
 
@@ -679,5 +686,5 @@
 
     // Please insert fields in alphabetical order and group them into messages
     // if possible (to avoid reaching the method limit).
-    // Next tag = 93;
+    // Next tag = 94;
 }
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..3fbd797 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
@@ -6512,6 +6515,13 @@
     <permission android:name="android.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS"
                 android:protectionLevel="signature|privileged" />
 
+    <!-- Allows an app to set gesture exclusion without restrictions on the vertical extent of the
+         exclusions (see {@link android.view.View#setSystemGestureExclusionRects}).
+         @hide
+    -->
+    <permission android:name="android.permission.SET_UNRESTRICTED_GESTURE_EXCLUSION"
+                android:protectionLevel="signature|privileged|recents" />
+
     <!-- @SystemApi Allows TV input apps and TV apps to use TIS extension interfaces for
          domain-specific features.
          <p>Protection level: signature|privileged|vendorPrivileged
@@ -6532,6 +6542,12 @@
     <permission android:name="android.permission.MAKE_UID_VISIBLE"
                 android:protectionLevel="signature" />
 
+    <!-- Limits the system as the only handler of the QUERY_PACKAGE_RESTART broadcast
+         @hide -->
+    <permission android:name="android.permission.HANDLE_QUERY_PACKAGE_RESTART"
+                android:protectionLevel="signature" />
+    <uses-permission android:name="android.permission.HANDLE_QUERY_PACKAGE_RESTART" />
+
     <!-- Attribution for Geofencing service. -->
     <attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
     <!-- Attribution for Country Detector. -->
@@ -7071,6 +7087,10 @@
                  android:permission="android.permission.BIND_JOB_SERVICE">
         </service>
 
+        <service android:name="com.android.server.notification.NotificationHistoryJobService"
+                 android:permission="android.permission.BIND_JOB_SERVICE" >
+        </service>
+
         <service android:name="com.android.server.pm.PackageManagerShellCommandDataLoader"
             android:exported="false">
             <intent-filter>
diff --git a/core/res/res/layout-car/car_alert_dialog.xml b/core/res/res/layout-car/car_alert_dialog.xml
index 2e7b62c..3c7a5c5 100644
--- a/core/res/res/layout-car/car_alert_dialog.xml
+++ b/core/res/res/layout-car/car_alert_dialog.xml
@@ -54,7 +54,7 @@
                     android:layout_height="wrap_content"
                     android:layout_marginStart="@dimen/text_view_start_margin"
                     android:layout_marginEnd="@dimen/text_view_end_margin"
-                    style="@style/CarBody4"/>
+                    style="@style/CarDialogMessageText"/>
 
                 <!-- we don't need this spacer, but the id needs to be here for compatibility -->
                 <Space
diff --git a/core/res/res/layout-car/car_alert_dialog_button_bar.xml b/core/res/res/layout-car/car_alert_dialog_button_bar.xml
index 4f815b8..43fd1eb 100644
--- a/core/res/res/layout-car/car_alert_dialog_button_bar.xml
+++ b/core/res/res/layout-car/car_alert_dialog_button_bar.xml
@@ -16,13 +16,13 @@
   -->
 
 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-            android:id="@+id/buttonPanel"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:scrollbarAlwaysDrawVerticalTrack="true"
-            android:scrollIndicators="top|bottom"
-            android:fillViewport="true"
-            style="?attr/buttonBarStyle">
+    android:id="@+id/buttonPanel"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:scrollbarAlwaysDrawVerticalTrack="true"
+    android:scrollIndicators="top|bottom"
+    android:fillViewport="true"
+    style="?attr/buttonBarStyle">
     <com.android.internal.widget.ButtonBarLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
@@ -35,7 +35,7 @@
 
         <Button
             android:id="@+id/button3"
-            style="@style/CarAction1"
+            style="@style/CarDialogButtonText"
             android:minWidth="@dimen/car_touch_target_size"
             android:paddingStart="@dimen/car_padding_2"
             android:paddingEnd="@dimen/car_padding_2"
@@ -46,7 +46,7 @@
 
         <Button
             android:id="@+id/button2"
-            style="@style/CarAction1"
+            style="@style/CarDialogButtonText"
             android:minWidth="@dimen/car_touch_target_size"
             android:paddingStart="@dimen/car_padding_2"
             android:paddingEnd="@dimen/car_padding_2"
@@ -57,7 +57,7 @@
 
         <Button
             android:id="@+id/button1"
-            style="@style/CarAction1"
+            style="@style/CarDialogButtonText"
             android:minWidth="@dimen/car_touch_target_size"
             android:paddingStart="@dimen/car_padding_2"
             android:paddingEnd="@dimen/car_padding_2"
diff --git a/core/res/res/layout/transient_notification_with_icon.xml b/core/res/res/layout/transient_notification_with_icon.xml
new file mode 100644
index 0000000..e9b17df
--- /dev/null
+++ b/core/res/res/layout/transient_notification_with_icon.xml
@@ -0,0 +1,46 @@
+<?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.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:gravity="center_vertical"
+    android:maxWidth="@dimen/toast_width"
+    android:background="?android:attr/toastFrameBackground"
+    android:elevation="@dimen/toast_elevation"
+    android:layout_marginEnd="16dp"
+    android:layout_marginStart="16dp"
+    android:paddingStart="16dp"
+    android:paddingEnd="16dp">
+
+    <ImageView
+        android:id="@android:id/icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <TextView
+        android:id="@android:id/message"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:ellipsize="end"
+        android:maxLines="2"
+        android:paddingTop="12dp"
+        android:paddingBottom="12dp"
+        android:textAppearance="@style/TextAppearance.Toast"/>
+</LinearLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index d1c3876..110cde3 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Hierdie toetstel het nie \'n vingerafdruksensor nie."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor is tydelik gedeaktiveer."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Kan nie vingerafdruksensor gebruik nie. Besoek \'n verskaffer wat herstelwerk doen"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gebruik vingerafdruk"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gebruik vingerafdruk of skermslot"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KAART <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 21751c8..9f3a28b 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ይህ መሣሪያ የጣት አሻራ ዳሳሽ የለውም።"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ዳሳሽ ለጊዜው ተሰናክሏል።"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"የጣት አሻራ ዳሳሽን መጠቀም አይቻልም። የጥገና አገልግሎት ሰጪን ይጎብኙ"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ጣት <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"የጣት አሻራ ይጠቀሙ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"የጣት አሻራ ወይም የማያ ገጽ መቆለፊያ ይጠቀሙ"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"ካርድ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index b75f962..f0d7af3 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>
@@ -613,6 +615,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"لا يحتوي هذا الجهاز على مستشعِر بصمات إصبع."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"تم إيقاف جهاز الاستشعار مؤقتًا."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"لا يمكن استخدام أداة استشعار بصمة الإصبع. يُرجى التواصل مع مقدِّم خدمات إصلاح."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"الإصبع <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استخدام بصمة الإصبع"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استخدام بصمة الإصبع أو قفل الشاشة"</string>
@@ -2079,10 +2083,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 +2292,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"‏رقم البطاقة ‎<xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index c1c1e96..d6393e9 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইচটোত ফিংগাৰপ্ৰিণ্ট ছেন্সৰ নাই।"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ছেন্সৰটো সাময়িকভাৱে অক্ষম হৈ আছে।"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰ ব্যৱহাৰ কৰিব নোৱাৰি। মেৰামতি সেৱা প্ৰদানকাৰী কোনো প্ৰতিষ্ঠানলৈ যাওক"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> আঙুলি"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ফিংগাৰপ্ৰিণ্ট অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
@@ -2075,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>
@@ -2286,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"কাৰ্ড <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 8343ae6..2e80e87 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda barmaq izi sensoru yoxdur."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor müvəqqəti deaktivdir."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Barmaq izi sensorundan istifadə etmək mümkün deyil. Təmir provayderini ziyarət edin"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Barmaq <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmaq izini istifadə edin"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Barmaq izi və ya ekran kilidindən istifadə edin"</string>
@@ -2075,10 +2079,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KART <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </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..1a40450 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>
@@ -610,6 +612,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ne možete da koristite senzor za otisak prsta. Posetite dobavljača za popravke"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristite otisak prsta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristite otisak prsta ili zaključavanje ekrana"</string>
@@ -2285,4 +2289,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KARTICA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 7c313c8..3477400 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>
@@ -611,6 +613,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На гэтай прыладзе няма сканера адбіткаў пальцаў."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчык часова выключаны."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не ўдалося скарыстаць сканер адбіткаў пальцаў. Звярніцеся ў сэрвісны цэнтр."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Выкарыстоўваць адбітак пальца"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Выкарыстоўваць адбітак пальца ці блакіроўку экрана"</string>
@@ -2077,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 Адаптыўныя апавяшчэнні 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 +2290,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"КАРТА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index d52e3e2..89ffe40 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Това устройство няма сензор за отпечатъци."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорът е временно деактивиран."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Сензорът за отпечатъци не може да се използва. Посетете оторизиран сервиз."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Пръст <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Използване на отпечатък"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Използване на отпечатък или опцията за заключване на екрана"</string>
@@ -2075,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>
@@ -2286,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"КАРТА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 7ba759f..0882853 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইসে আঙ্গুলের ছাপ নেওয়ার সেন্সর নেই।"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"সেন্সর অস্থায়ীভাবে বন্ধ করা আছে।"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"আঙ্গুলের ছাপের সেন্সর ব্যবহার করা যাচ্ছে না। একজন মেরামতি মিস্ত্রির কাছে যান"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"আঙ্গুল <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"আঙ্গুলের ছাপ ব্যবহার করুন"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"আঙ্গুলের ছাপ অথবা স্ক্রিন লক ব্যবহার করুন"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"কার্ড <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 5616dd8..96b17fb7 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>
@@ -610,6 +612,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Nije moguće koristiti senzor za otisak prsta. Posjetite pružaoca usluga za popravke"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristi otisak prsta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristi otisak prsta ili zaključavanje ekrana"</string>
@@ -2076,8 +2080,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 +2289,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KARTICA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 70faff5..999eb2d 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aquest dispositiu no té sensor d\'empremtes digitals."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor està desactivat temporalment."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"No es pot utilitzar el sensor d\'empremtes digitals. Visita un proveïdor de reparacions."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dit <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilitza l\'empremta digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilitza l\'empremta digital o el bloqueig de pantalla"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"TARGETA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index c42b888..95ce5a8 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>
@@ -611,6 +613,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zařízení nemá snímač otisků prstů."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasně deaktivován."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Snímač otisků prstů nelze použít. Navštivte servis"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Použít otisk prstu"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Použít otisk prstu nebo zámek obrazovky"</string>
@@ -2286,4 +2290,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KARTA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 80476bb..b8fd910 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enhed har ingen fingeraftrykslæser."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidigt deaktiveret."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Fingeraftrykslæseren kan ikke bruges. Få den repareret"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Fingeraftryk <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Brug fingeraftryk"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Brug fingeraftryk eller skærmlås"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KORT <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 4cfb46f..f1d30c3d 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dieses Gerät hat keinen Fingerabdrucksensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Der Sensor ist vorübergehend deaktiviert."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Der Fingerabdrucksensor kann nicht verwendet werden. Suche einen Reparaturdienstleister auf."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Fingerabdruck verwenden"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Fingerabdruck oder Displaysperre verwenden"</string>
@@ -1625,7 +1629,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 +2079,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KARTE <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index b246d0b..c274a18 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Αυτή η συσκευή δεν διαθέτει αισθητήρα δακτυλικού αποτυπώματος."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Ο αισθητήρας απενεργοποιήθηκε προσωρινά."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Δεν είναι δυνατή η χρήση του αισθητήρα δακτυλικών αποτυπωμάτων. Επισκεφτείτε έναν πάροχο υπηρεσιών επισκευής."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Δάχτυλο <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Χρήση δακτυλικού αποτυπώματος"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Χρήση δακτυλικού αποτυπώματος ή κλειδώματος οθόνης"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"ΚΑΡΤΑ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 32ad56dc..bc376e1 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
@@ -2284,4 +2288,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-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index a678b28..b9109c3 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
@@ -2284,4 +2288,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-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 38c97db..88740da 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
@@ -2284,4 +2288,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-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 06dd854..39c4da2 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
@@ -2284,4 +2288,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-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 1bac742..da55825 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎This device does not have a fingerprint sensor.‎‏‎‎‏‎"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎Sensor temporarily disabled.‎‏‎‎‏‎"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎Can’t use fingerprint sensor. Visit a repair provider‎‏‎‎‏‎"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‎Finger ‎‏‎‎‏‏‎<xliff:g id="FINGERID">%d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‎‎‏‎‎‎Use fingerprint‎‏‎‎‏‎"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‏‎‎‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎Use fingerprint or screen lock‎‏‎‎‏‎"</string>
@@ -2284,4 +2288,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..a13392c 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas dactilares."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Se inhabilitó temporalmente el sensor."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"No se puede usar el sensor de huellas dactilares. Consulta a un proveedor de reparaciones."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar huella dactilar"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar bloqueo de huella dactilar o pantalla"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"TARJETA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 408d71d..788bbbc 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas digitales."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor está inhabilitado en estos momentos."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"No se puede usar el sensor de huellas digitales. Visita un proveedor de reparaciones."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar huella digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar huella digital o bloqueo de pantalla"</string>
@@ -2075,10 +2079,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"TARJETA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index cbfe44b..f1dc281 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Selles seadmes pole sõrmejäljeandurit."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Andur on ajutiselt keelatud."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Sõrmejäljeandurit ei saa kasutada. Külastage remonditeenuse pakkujat"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Sõrmejälg <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Sõrmejälje kasutamine"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Sõrmejälje või ekraaniluku kasutamine"</string>
@@ -2075,10 +2079,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KAART <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 4d955bb..0469caa 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Gailu honek ez du hatz-marken sentsorerik."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sentsorea aldi baterako desgaitu da."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ezin da erabili hatz-marken sentsorea. Jarri harremanetan konponketak egiten dituen hornitzaile batekin."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. hatza"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Erabili hatz-marka"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Erabili hatz-marka edo pantailaren blokeoa"</string>
@@ -618,7 +622,7 @@
   </string-array>
     <string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"Arazo bat izan da. Saiatu berriro."</string>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Hatz-markaren ikonoa"</string>
-    <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Aurpegi bidez desblokeatzeko eginbidea"</string>
+    <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Aurpegi bidez desblokeatzea"</string>
     <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Arazoak ditugu aurpegi bidez desblokeatzeko eginbidearekin"</string>
     <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Sakatu hau aurpegi-eredua ezabatzeko eta, gero, gehitu aurpegia berriro"</string>
     <string name="face_setup_notification_title" msgid="8843461561970741790">"Konfiguratu aurpegi bidez desblokeatzeko eginbidea"</string>
@@ -988,7 +992,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"Zabaldu desblokeatzeko eremua."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"Hatza lerratuta desblokeatzea."</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"Ereduaren bidez desblokeatzea."</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Aurpegi bidez desblokeatzeko eginbidea."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Aurpegi bidez desblokeatzea."</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"PIN kodearen bidez desblokeatzea."</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"SIMa desblokeatzeko PINa."</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"SIM txartela desblokeatzeko PUK kodea."</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"<xliff:g id="CARDNUMBER">%d</xliff:g> TXARTELA"</string>
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d15780c..7582280 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"این دستگاه حسگر اثر انگشت ندارد."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"حسگر به‌طور موقت غیرفعال است."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"امکان استفاده از حسگر اثر انگشت وجود ندارد. به ارائه‌دهنده خدمات تعمیر مراجعه کنید"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"انگشت <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استفاده از اثر انگشت"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استفاده از اثر انگشت یا قفل صفحه"</string>
@@ -623,7 +627,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 +1050,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 +2079,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 +2272,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"کارت <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 33b43ba..36eb2e0 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Laitteessa ei ole sormenjälkitunnistinta."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tunnistin poistettu väliaikaisesti käytöstä."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Sormenjälkitunnistinta ei voi käyttää. Ota yhteys korjauspalveluun"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Sormi <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Käytä sormenjälkeä"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Käytä sormenjälkeä tai näytön lukitusta"</string>
@@ -2075,10 +2079,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"Kortti: <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 23b8f04..a84eebb 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Cet appareil ne possède pas de capteur d\'empreintes digitales."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Le capteur a été désactivé temporairement."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Impossible d\'utiliser le capteur d\'empreintes digitales. Consultez un fournisseur de services de réparation"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utiliser l\'empreinte digitale ou le verrouillage de l\'écran"</string>
@@ -2075,10 +2079,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"CARTE <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index e14d506..0bc5e74 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aucun lecteur d\'empreinte digitale n\'est installé sur cet appareil."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Capteur temporairement désactivé."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Impossible d\'utiliser le lecteur d\'empreinte digitale. Contactez un réparateur"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utiliser votre empreinte digitale ou le verrouillage de l\'écran"</string>
@@ -623,7 +627,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 +2079,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"CARTE <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 72f0dcc..4663e0b 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo non ten sensor de impresión dixital."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Desactivouse o sensor temporalmente."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Non se puido usar o sensor de impresión dixital. Visita un provedor de reparacións"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilizar impresión dixital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilizar impresión dixital ou credencial do dispositivo"</string>
@@ -2075,17 +2079,15 @@
     <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>
     <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"A tableta non ten suficiente batería. Xa non se restrinxirán as funcións."</string>
     <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"O dispositivo non ten suficiente batería. Xa non se restrinxirán as funcións."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Cartafol"</string>
-    <string name="mime_type_apk" msgid="3168784749499623902">"Aplicación Android"</string>
+    <string name="mime_type_apk" msgid="3168784749499623902">"Aplicación para Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Ficheiro"</string>
     <string name="mime_type_generic_ext" msgid="9220220924380909486">"Ficheiro <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
     <string name="mime_type_audio" msgid="4933450584432509875">"Audio"</string>
@@ -2286,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"TARXETA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index f1f0b86..6a28ef1 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"આ ડિવાઇસમાં કોઈ ફિંગરપ્રિન્ટ સેન્સર નથી."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"સેન્સર હંગામી રૂપે બંધ કર્યું છે."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ફિંગરપ્રિન્ટ સેન્સરનો ઉપયોગ કરી શકાતો નથી. રિપેર કરવાની સેવા આપતા પ્રદાતાની મુલાકાત લો"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"આંગળી <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ફિંગરપ્રિન્ટ અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"કાર્ડ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 6d90d53..4fa1624 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"इस डिवाइस में फ़िंगरप्रिंट सेंसर नहीं है."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेंसर कुछ समय के लिए बंद कर दिया गया है."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"फ़िंगरप्रिंट सेंसर इस्तेमाल नहीं किया जा सकता. रिपेयर की सेवा देने वाली कंपनी से संपर्क करें"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"फ़िंगरप्रिंट <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फ़िंगरप्रिंट इस्तेमाल करें"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फ़िंगरप्रिंट या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
@@ -636,17 +640,17 @@
     <string name="face_acquired_too_far" msgid="2922278214231064859">"फ़ोन को नज़दीक लाएं"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"फ़ोन को थोड़ा और ऊपर ले जाएं"</string>
     <string name="face_acquired_too_low" msgid="4075391872960840081">"फ़ोन को थोड़ा नीचे ले जाएं"</string>
-    <string name="face_acquired_too_right" msgid="6245286514593540859">"फ़ोन को अपनी बाईं ओर ले जाएं"</string>
-    <string name="face_acquired_too_left" msgid="9201762240918405486">"फ़ोन को अपनी दाईं ओर ले जाएं"</string>
+    <string name="face_acquired_too_right" msgid="6245286514593540859">"फ़ोन को अपने बाईं ओर ले जाएं"</string>
+    <string name="face_acquired_too_left" msgid="9201762240918405486">"फ़ोन को अपने दाईं ओर ले जाएं"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"कृपया अपने डिवाइस की तरफ़ सीधे देखें."</string>
     <string name="face_acquired_not_detected" msgid="1057966913397548150">"आपका चेहरा नहीं दिख रहा है. फ़ोन को अपनी आंखों की सीध में पकड़कर रखें."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"डिवाइस बहुत ज़्यादा हिल रहा है. फ़ोन को बिना हिलाएं पकड़ें."</string>
     <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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"कार्ड <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 63782e8..3b6a61c 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>
@@ -610,6 +612,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor otiska prsta."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Senzor otiska prsta ne može se koristiti. Posjetite davatelja usluga popravaka"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Upotreba otiska prsta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Upotreba otiska prsta ili zaključavanja zaslona"</string>
@@ -2285,4 +2289,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KARTICA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index ed656ac..32c734c 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ez az eszköz nem rendelkezik ujjlenyomat-érzékelővel."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Az érzékelő átmenetileg le van tiltva."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Nem lehet használni az ujjlenyomat-érzékelőt. Keresse fel a szervizt."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. ujj"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Ujjlenyomat használata"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"A folytatás ujjlenyomattal vagy képernyőzárral lehetséges"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KÁRTYA: <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 282a212..c69f467 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Այս սարքը չունի մատնահետքերի սկաներ։"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Տվիչը ժամանակավորապես անջատված է:"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Մատնահետքերի սկաները հնարավոր չէ օգտագործել։ Այցելեք սպասարկման կենտրոն։"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Մատնահետք <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Օգտագործել մատնահետք"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Օգտագործել մատնահետք կամ էկրանի կողպում"</string>
@@ -2075,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>
@@ -2286,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"ՔԱՐՏ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index a5fa54d..6ada180 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Perangkat ini tidak memiliki sensor sidik jari."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor dinonaktifkan untuk sementara."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Tidak dapat menggunakan sensor sidik jari. Kunjungi penyedia reparasi"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gunakan sidik jari"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gunakan sidik jari atau kunci layar"</string>
@@ -745,7 +749,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 +2079,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KARTU <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index ff29303..6bf2f54 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Þetta tæki er ekki með fingrafaralesara."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Slökkt tímabundið á skynjara."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ekki er hægt að nota fingrafaralesara. Þú verður að fara með hann á verkstæði"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Fingur <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Nota fingrafar"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Nota fingrafar eða skjálás"</string>
@@ -2075,10 +2079,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KORT <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 89367e1..8c00495 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Questo dispositivo non dispone di sensore di impronte."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensore temporaneamente disattivato."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Impossibile usare il sensore di impronte digitali. Contatta un fornitore di servizi di riparazione"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usa l\'impronta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usa l\'impronta o il blocco schermo"</string>
@@ -636,8 +640,8 @@
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Avvicina il telefono"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Sposta il telefono più in alto"</string>
     <string name="face_acquired_too_low" msgid="4075391872960840081">"Sposta il telefono più in basso"</string>
-    <string name="face_acquired_too_right" msgid="6245286514593540859">"Sposta il telefono alla tua sinistra"</string>
-    <string name="face_acquired_too_left" msgid="9201762240918405486">"Sposta il telefono alla tua destra"</string>
+    <string name="face_acquired_too_right" msgid="6245286514593540859">"Sposta il telefono verso sinistra"</string>
+    <string name="face_acquired_too_left" msgid="9201762240918405486">"Sposta il telefono verso destra"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Guarda più direttamente verso il dispositivo."</string>
     <string name="face_acquired_not_detected" msgid="1057966913397548150">"Impossibile vedere il volto. Tieni il telefono all\'altezza degli occhi."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Troppo movimento. Tieni fermo il telefono."</string>
@@ -1916,13 +1920,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"SCHEDA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index bbc2581..5afe502 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>
@@ -611,6 +613,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"במכשיר הזה אין חיישן טביעות אצבע."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"החיישן מושבת באופן זמני."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"לא ניתן להשתמש בחיישן טביעות האצבע. צריך ליצור קשר עם ספק תיקונים"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"שימוש בטביעת אצבע"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"שימוש בטביעת אצבע או בנעילת מסך"</string>
@@ -2286,4 +2290,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"כרטיס <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 60d0b91..404a18a 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"このデバイスには指紋認証センサーがありません。"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"センサーが一時的に無効になっています。"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"指紋認証センサーを使用できません。修理業者に調整を依頼してください"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"指紋 <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"指紋の使用"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"指紋または画面ロックの使用"</string>
@@ -1443,7 +1447,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"カード <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 9974606..5793ed7 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ამ მოწყობილობას არ აქვს თითის ანაბეჭდის სენსორი."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"სენსორი დროებით გათიშულია."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"თითის ანაბეჭდის სენსორის გამოყენება ვერ ხერხდება. ეწვიეთ შეკეთების სერვისის პროვაიდერს"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"თითი <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"გამოიყენეთ თითის ანაბეჭდი"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"გამოიყენეთ თითის ანაბეჭდი ან ეკრანის დაბლოკვა"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"ბარათი <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 3545559..69a1988 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бұл құрылғыда саусақ ізін оқу сканері жоқ."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик уақытша өшірулі."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Саусақ ізін оқу сканерін пайдалану мүмкін емес. Жөндеу қызметіне барыңыз."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-саусақ"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Саусақ ізін пайдалану"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Саусақ ізін немесе экран құлпын пайдалану"</string>
@@ -1134,7 +1138,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 +1383,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 +1482,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 +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>
@@ -2286,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"<xliff:g id="CARDNUMBER">%d</xliff:g>-КАРТА"</string>
 </resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 2da5ac0..72cd8172 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ឧបករណ៍នេះ​មិនមាន​ឧបករណ៍ចាប់​ស្នាមម្រាមដៃទេ។"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"បានបិទ​ឧបករណ៍​ចាប់សញ្ញាជា​បណ្តោះអាសន្ន។"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"មិនអាចប្រើ​ឧបករណ៍ចាប់ស្នាមម្រាមដៃ​បានទេ។ សូមទាក់ទង​ក្រុមហ៊ុនផ្ដល់​ការជួសជុល"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ម្រាមដៃ <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ប្រើស្នាមម្រាមដៃ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ប្រើស្នាមម្រាមដៃ ឬ​ការចាក់សោអេក្រង់"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"កាត <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 4b90f4d..1f1950e 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ಈ ಸಾಧನವು ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌‌ ಅನ್ನು ಹೊಂದಿಲ್ಲ."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ಸೆನ್ಸಾರ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಬಳಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ರಿಪೇರಿ ಮಾಡುವವರನ್ನು ಸಂಪರ್ಕಿಸಿ"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ಫಿಂಗರ್ <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಬಳಸಿ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಬಳಸಿ"</string>
@@ -634,7 +638,7 @@
     <string name="face_acquired_too_dark" msgid="7919016380747701228">"ಪ್ರಕಾಶಮಾನವಾದ ಲೈಟಿಂಗ್ ಬಳಸಿ"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"ಫೋನ್ ಅನ್ನು ದೂರಕ್ಕೆ ಸರಿಸಿ"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"ಫೋನ್ ಅನ್ನು ಸಮೀಪಕ್ಕೆ ತನ್ನಿ"</string>
-    <string name="face_acquired_too_high" msgid="8278815780046368576">"ಫೋನ್ ಅನ್ನು ಎತ್ತರಕ್ಕೆ ಹಿಡಿಯಿರಿ"</string>
+    <string name="face_acquired_too_high" msgid="8278815780046368576">"ಫೋನ್ ಅನ್ನು ಮೇಲಕ್ಕೆ ಎತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
     <string name="face_acquired_too_low" msgid="4075391872960840081">"ಫೋನ್ ಅನ್ನು ಕೆಳಗೆ ಸರಿಸಿ"</string>
     <string name="face_acquired_too_right" msgid="6245286514593540859">"ಫೋನ್ ಅನ್ನು ನಿಮ್ಮ ಎಡಕ್ಕೆ ಸರಿಸಿ"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"ಫೋನ್ ಅನ್ನು ನಿಮ್ಮ ಬಲಕ್ಕೆ ಸರಿಸಿ"</string>
@@ -1355,8 +1359,8 @@
     <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_message" msgid="5617264033476778211">"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>
     <string name="adbwifi_active_notification_message" msgid="930987922852867972">"ವೈರ್‌ಲೆಸ್ ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ಆಫ್‌ ಮಾಡಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"ಕಾರ್ಡ್ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index d75f3a8..fc80ec0 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"기기에 지문 센서가 없습니다."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"센서가 일시적으로 사용 중지되었습니다."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"지문 센서를 사용할 수 없습니다. 수리업체에 방문하세요."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"손가락 <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"지문 사용"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"지문 또는 화면 잠금 사용"</string>
@@ -2075,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>
@@ -2286,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"<xliff:g id="CARDNUMBER">%d</xliff:g> 카드"</string>
 </resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index b9d681c..70beacb 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бул түзмөктө манжа изинин сенсору жок."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сенсор убактылуу өчүрүлгөн."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Манжа изинин сенсорун колдонууга болбойт. Тейлөө кызматына кайрылыңыз"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-манжа"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Манжа изин колдонуу"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Манжа изин же экрандын кулпусун колдонуу"</string>
@@ -621,7 +625,7 @@
     <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Жүзүнөн таанып ачуу"</string>
     <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Жүзүнөн таанып ачуу функциясында маселе келип чыкты"</string>
     <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Жүзүңүздүн үлгүсүн өчүрүү үчүн басып, жаңы үлгүнү кошуңуз"</string>
-    <string name="face_setup_notification_title" msgid="8843461561970741790">"Жүзүнөн таанып ачууну жөндөө"</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">"Жүзүнөн таанып ачуу функциясын колдонуу үчүн Жөндөөлөр &gt; Купуялык бөлүмүнө өтүп, "<b>"Камераны колдонууну"</b>" күйгүзүңүз"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Кулпусун ачуунун көбүрөөк жолдорун жөндөңүз"</string>
@@ -1229,7 +1233,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"КАРТА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index eeae8ce..2436627 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ອຸປະກອນນີ້ບໍ່ມີເຊັນເຊີລາຍນິ້ວມື."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ປິດການເຮັດວຽກຂອງເຊັນເຊີໄວ້ຊົ່ວຄາວແລ້ວ."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ບໍ່ສາມາດໃຊ້ເຊັນ​ເຊີລາຍນິ້ວ​ມືໄດ້. ກະລຸນາໄປຫາຜູ້ໃຫ້ບໍລິການສ້ອມແປງ"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ນີ້ວ​ມື <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ໃຊ້ລາຍນິ້ວມື"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ໃຊ້ລາຍນິ້ວມື ຫຼື ການລັອກໜ້າຈໍ"</string>
@@ -2075,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 ຖືກແທນທີ່ດ້ວຍການແຈ້ງເຕືອນທີ່ປັບປຸງໃຫ້ດີຂຶ້ນໃນ 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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"ບັດ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index f68b292..641b4da 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>
@@ -611,6 +613,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šiame įrenginyje nėra kontrolinio kodo jutiklio."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Jutiklis laikinai išjungtas."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Negalima naudoti kontrolinio kodo jutiklio. Apsilankykite pas taisymo paslaugos teikėją"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> pirštas"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Naudoti kontrolinį kodą"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Naudoti kontrolinį kodą arba ekrano užraktą"</string>
@@ -2286,4 +2290,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KORTELĖ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index d2bb73c..3adf133 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>
@@ -610,6 +612,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šajā ierīcē nav pirksta nospieduma sensora."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensors ir īslaicīgi atspējots."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Nevar izmantot pirksta nospieduma sensoru. Sazinieties ar remonta pakalpojumu sniedzēju."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. pirksts"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Pirksta nospieduma izmantošana"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Pirksta nospieduma vai ekrāna bloķēšanas metodes izmantošana"</string>
@@ -2076,10 +2080,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 +2289,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KARTE <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-mcc334-mnc020-pa/strings.xml b/core/res/res/values-mcc334-mnc020-pa/strings.xml
index 3cf6bc8..23f77d8 100644
--- a/core/res/res/values-mcc334-mnc020-pa/strings.xml
+++ b/core/res/res/values-mcc334-mnc020-pa/strings.xml
@@ -21,6 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="config_pdp_reject_dialog_title" msgid="41208110171880430"></string>
     <string name="config_pdp_reject_user_authentication_failed" msgid="4683454131283459978">"ਪ੍ਰਮਾਣੀਕਰਨ ਅਸਫਲ -29-"</string>
-    <string name="config_pdp_reject_service_not_subscribed" msgid="9021140729932308119">"ਸੇਵਾ ਦੀ ਗਾਹਕੀ ਨਹੀਂ ਲਈ -33-"</string>
+    <string name="config_pdp_reject_service_not_subscribed" msgid="9021140729932308119">"ਸੇਵਾ ਨੂੰ ਸਬਸਕ੍ਰਾਈਬ ਨਹੀਂ ਕੀਤਾ -33-"</string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="3838388706348367865">"ਕਿਸੇ ਵੀ APN ਲਈ ਇੱਕ ਤੋਂ ਵੱਧ PDN ਕਨੈਕਸ਼ਨਾਂ ਦੀ ਆਗਿਆ ਨਹੀਂ ਹੈ -55-"</string>
 </resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 0df4312..a93be12 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Уредов нема сензор за отпечатоци."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорот е привремено оневозможен."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не може да се користи сензорот за отпечатоци. Однесете го на поправка"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користи отпечаток"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користи отпечаток или заклучување екран"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"КАРТИЧКА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index f18fb00..67d6e67 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ഈ ഉപകരണത്തിൽ ഫിംഗർപ്രിന്റ് സെൻസറില്ല."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"സെൻസർ താൽക്കാലികമായി പ്രവർത്തനരഹിതമാക്കി."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"വിരലടയാള സെൻസർ ഉപയോഗിക്കാനാകുന്നില്ല. റിപ്പയർ കേന്ദ്രം സന്ദർശിക്കുക"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ഫിംഗർ <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ഫിംഗർപ്രിന്റ് അല്ലെങ്കിൽ സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
@@ -1013,7 +1017,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"കാർഡ് <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 3b679c8..e36dd56 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Энэ төхөөрөмжид хурууны хээ мэдрэгч алга."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Мэдрэгчийг түр хугацаанд идэвхгүй болгосон."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Хурууны хээ мэдрэгч ашиглах боломжгүй. Засварын үйлчилгээ үзүүлэгчид зочилно уу"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Хурууны хээ <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Хурууны хээ ашиглах"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Хурууны хээ эсвэл дэлгэцийн түгжээ ашиглах"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"КАРТ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 0477a06..894c264 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"या डिव्हाइसमध्ये फिंगरप्रिंट सेन्सर नाही."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेन्सर तात्पुरता बंद केला आहे."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"फिंगरप्रिंट सेन्सर वापरू शकत नाही. दुरुस्तीच्या सेवा पुरवठादाराला भेट द्या"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> बोट"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फिंगरप्रिंट वापरा"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फिंगरप्रिंट किंवा स्क्रीन लॉक वापरा"</string>
@@ -647,7 +651,7 @@
     <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_obscured" msgid="4917643294953326639">"तुमचा चेहरा लपवणारे काहीही काढून टाका."</string>
     <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"ब्लॅक बार सह तुमच्या स्क्रीनची वरची बाजू साफ करा"</string>
     <string name="face_acquired_dark_glasses_detected" msgid="7263638432128692048">"तुमचा चेहरा पूर्णपणे दृश्यमान असणे आवश्यक आहे"</string>
     <string name="face_acquired_mouth_covering_detected" msgid="615991670821926847">"तुमचा चेहरा पूर्णपणे दृश्यमान असणे आवश्यक आहे"</string>
@@ -693,7 +697,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 +733,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"कार्ड <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index cfb8739..7a3c7ef 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Peranti ini tiada penderia cap jari."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Penderia dilumpuhkan sementara."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Tidak boleh menggunakan penderia cap jari. Lawati penyedia pembaikan"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gunakan cap jari"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gunakan cap jari atau kunci skrin"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KAD <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 07e54a6..770deed 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ဤစက်တွင် လက်ဗွေအာရုံခံကိရိယာ မရှိပါ။"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"အာရုံခံကိရိယာကို ယာယီပိတ်ထားသည်။"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"လက်ဗွေ အာရုံခံကိရိယာကို အသုံးပြု၍ မရပါ။ ပြုပြင်ရေး ဝန်ဆောင်မှုပေးသူထံသို့ သွားပါ"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"လက်ချောင်း <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"လက်ဗွေ သုံးခြင်း"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"လက်ဗွေ (သို့) ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"ကတ် <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index d5d230b..caa1900 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enheten har ikke fingeravtrykkssensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidig slått av."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Kan ikke bruke fingeravtrykkssensoren. Gå til en reparasjonsleverandør"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Bruk fingeravtrykk"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Bruk fingeravtrykk eller skjermlås"</string>
@@ -1036,9 +1040,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 +2079,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KORT <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 6f10404..d581c67 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"यो डिभाइसमा कुनै पनि फिंगरप्रिन्ट सेन्सर छैन।"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"केही समयका लागि सेन्सर असक्षम पारियो।"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"फिंगरप्रिन्ट सेन्सर प्रयोग गर्न मिल्दैन। फिंगरप्रिन्ट सेन्सर मर्मत गर्ने सेवा प्रदायक कम्पनीमा सम्पर्क गर्नुहोस्"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"औंला <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फिंगरप्रिन्ट वा स्क्रिन लक प्रयोग गर्नुहोस्"</string>
@@ -2075,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 १२ मा 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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"कार्ड <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 6c4b68e..210ce12 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dit apparaat heeft geen vingerafdruksensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor staat tijdelijk uit."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Kan vingerafdruksensor niet gebruiken. Ga naar een reparateur."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Vingerafdruk gebruiken"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Vingerafdruk of schermvergrendeling gebruiken"</string>
@@ -647,7 +651,7 @@
     <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Kijk goed recht naar je telefoon"</string>
     <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Kijk goed recht naar je telefoon"</string>
     <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Kijk goed recht naar je telefoon"</string>
-    <string name="face_acquired_obscured" msgid="4917643294953326639">"Zorg dat je gezicht volledig zichtbaar is."</string>
+    <string name="face_acquired_obscured" msgid="4917643294953326639">"Zorg dat je gezicht volledig zichtbaar is"</string>
     <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Reinig de bovenkant van je scherm, inclusief de zwarte balk"</string>
     <string name="face_acquired_dark_glasses_detected" msgid="7263638432128692048">"Je gezicht moet geheel zichtbaar zijn"</string>
     <string name="face_acquired_mouth_covering_detected" msgid="615991670821926847">"Je gezicht moet geheel zichtbaar zijn"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KAART <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 331e300..05e34fe 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ଏହି ଡିଭାଇସ୍‌ରେ ଟିପଚିହ୍ନ ସେନ୍‍ସର୍ ନାହିଁ।"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ସେନ୍ସରକୁ ଅସ୍ଥାୟୀ ଭାବେ ଅକ୍ଷମ କରାଯାଇଛି।"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ଟିପଚିହ୍ନ ସେନ୍ସରକୁ ବ୍ୟବହାର କରାଯାଇପାରିବ ନାହିଁ। ଏକ ମରାମତି କେନ୍ଦ୍ରକୁ ଭିଜିଟ୍ କରନ୍ତୁ"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ଆଙ୍ଗୁଠି <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ଟିପଚିହ୍ନ ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
@@ -634,10 +638,10 @@
     <string name="face_acquired_too_dark" msgid="7919016380747701228">"ଉଜ୍ଜ୍ୱଳ ଲାଇଟ ବ୍ୟବହାର କରି ଦେଖନ୍ତୁ"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"ଫୋନକୁ ଟିକେ ଦୂରକୁ ନିଅନ୍ତୁ"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"ଫୋନକୁ ପାଖକୁ ଆଣନ୍ତୁ"</string>
-    <string name="face_acquired_too_high" msgid="8278815780046368576">"ଫୋନକୁ ଉପରକୁ ନିଅନ୍ତୁ"</string>
-    <string name="face_acquired_too_low" msgid="4075391872960840081">"ଫୋନକୁ ତଳକୁ ନିଅନ୍ତୁ"</string>
-    <string name="face_acquired_too_right" msgid="6245286514593540859">"ଫୋନକୁ ଆପଣଙ୍କ ବାମ ପଟକୁ ନିଅନ୍ତୁ"</string>
-    <string name="face_acquired_too_left" msgid="9201762240918405486">"ଫୋନକୁ ଆପଣଙ୍କ ଡାହାଣ ପଟକୁ ନିଅନ୍ତୁ"</string>
+    <string name="face_acquired_too_high" msgid="8278815780046368576">"ଫୋନକୁ ଉପରକୁ ମୁଭ କରନ୍ତୁ"</string>
+    <string name="face_acquired_too_low" msgid="4075391872960840081">"ଫୋନ୍‌କୁ ତଳକୁ ମୁଭ କରନ୍ତୁ"</string>
+    <string name="face_acquired_too_right" msgid="6245286514593540859">"ଫୋନକୁ ଆପଣଙ୍କ ବାମ ପଟକୁ ମୁଭ କରନ୍ତୁ"</string>
+    <string name="face_acquired_too_left" msgid="9201762240918405486">"ଫୋନକୁ ଆପଣଙ୍କ ଡାହାଣ ପଟକୁ ମୁଭ କରନ୍ତୁ"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"ଦୟାକରି ଆପଣଙ୍କ ଡିଭାଇସ୍‌କୁ ସିଧାସଳଖ ଦେଖନ୍ତୁ।"</string>
     <string name="face_acquired_not_detected" msgid="1057966913397548150">"ଆପଣଙ୍କ ଫେସ ଦେଖାଯାଉନାହିଁ। ଆପଣଙ୍କ ଫୋନକୁ ଆଖି ସିଧାରେ ଧରି ରଖନ୍ତୁ।"</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"ଅତ୍ୟଧିକ ଅସ୍ଥିର। ଫୋନ୍‍କୁ ସ୍ଥିର ଭାବେ ଧରନ୍ତୁ।"</string>
@@ -1151,9 +1155,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 +1178,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 +1322,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 +1359,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 +1545,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 +1568,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 +1694,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 +2049,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"କାର୍ଡ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 2f3294e..969b97f 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨਹੀਂ ਹੈ।"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ਸੈਂਸਰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਦੀ ਵਰਤੋਂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਮੁਰੰਮਤ ਪ੍ਰਦਾਨਕ \'ਤੇ ਜਾਓ"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ਉਂਗਲ <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਜਾਂ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
@@ -1267,7 +1271,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"ਕਾਰਡ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 55c4574..6c2aa0d 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>
@@ -611,6 +613,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"To urządzenie nie jest wyposażone w czytnik linii papilarnych."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Czujnik jest tymczasowo wyłączony."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Nie można użyć czytnika linii papilarnych. Odwiedź serwis."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Odcisk palca <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Używaj odcisku palca"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Używaj odcisku palca lub blokady ekranu"</string>
@@ -2286,4 +2290,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KARTA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index a02c200..99fd7b6 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Não foi possível usar o sensor de impressão digital. Entre em contato com uma assistência técnica"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar impressão digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar impressão digital ou bloqueio de tela"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"CHIP <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index d804c23..81029d6 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem sensor de impressões digitais."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporariamente desativado."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Não é possível usar o sensor de impressões digitais. Visite um fornecedor de serviços de reparação"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilizar a impressão digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilizar o bloqueio de ecrã ou a impressão digital"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"CARTÃO <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index a02c200..99fd7b6 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Não foi possível usar o sensor de impressão digital. Entre em contato com uma assistência técnica"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar impressão digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar impressão digital ou bloqueio de tela"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"CHIP <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 55ba527..2799431 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>
@@ -610,6 +612,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dispozitivul nu are senzor de amprentă."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzorul este dezactivat temporar."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Nu se poate folosi senzorul de amprentă. Vizitați un furnizor de servicii de reparații."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Degetul <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Folosiți amprenta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Folosiți amprenta sau blocarea ecranului"</string>
@@ -2285,4 +2289,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"CARD <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 1ef3c0c..c7a2cfe 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>
@@ -611,6 +613,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На этом устройстве нет сканера отпечатков пальцев."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сканер отпечатков пальцев временно отключен."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Невозможно использовать сканер отпечатков пальцев. Обратитесь в сервисный центр."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Отпечаток <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Использовать отпечаток пальца"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Использовать отпечаток пальца или блокировку экрана"</string>
@@ -636,10 +640,10 @@
     <string name="face_acquired_too_dark" msgid="7919016380747701228">"Сделайте освещение ярче"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Переместите телефон дальше от лица."</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Переместите телефон ближе к лицу"</string>
-    <string name="face_acquired_too_high" msgid="8278815780046368576">"Переместите телефон выше."</string>
-    <string name="face_acquired_too_low" msgid="4075391872960840081">"Переместите телефон ниже."</string>
-    <string name="face_acquired_too_right" msgid="6245286514593540859">"Переместите телефон левее."</string>
-    <string name="face_acquired_too_left" msgid="9201762240918405486">"Переместите телефон правее."</string>
+    <string name="face_acquired_too_high" msgid="8278815780046368576">"Переместите телефон выше"</string>
+    <string name="face_acquired_too_low" msgid="4075391872960840081">"Переместите телефон ниже"</string>
+    <string name="face_acquired_too_right" msgid="6245286514593540859">"Переместите телефон левее"</string>
+    <string name="face_acquired_too_left" msgid="9201762240918405486">"Переместите телефон правее"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Смотрите прямо на устройство."</string>
     <string name="face_acquired_not_detected" msgid="1057966913397548150">"Вашего лица не видно. Держите телефон на уровне глаз"</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Не перемещайте устройство. Держите его неподвижно."</string>
@@ -2077,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>
@@ -2288,4 +2290,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"КАРТА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 3f0d0e5..cc19efc 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"මෙම උපාංගයේ ඇඟිලි සලකුණු සංවේදකයක් නොමැත."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"සංවේදකය තාවකාලිකව අබල කර ඇත."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ඇඟිලි සලකුණු සංවේදකය භාවිත කළ නොහැකිය. අළුත්වැඩියා සැපයුම්කරුවෙකු බලන්න"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ඇඟිලි <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ඇඟිලි සලකුණ භාවිත කරන්න"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ඇඟිලි සලකුණ හෝ තිර අගුල භාවිත කරන්න"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"කාඩ්පත <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index fa4f98a..06467b0 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>
@@ -611,6 +613,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zariadenie nemá senzor odtlačkov prstov."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasne vypnutý."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Senzor odtlačkov prstov nie je možné používať. Navštívte poskytovateľa opráv."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst: <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Použiť odtlačok prsta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Použiť odtlačok prsta alebo zámku obrazovky"</string>
@@ -2062,7 +2066,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 +2290,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KARTA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 7cbd93e..605f5b0 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>
@@ -611,6 +613,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ta naprava nima tipala prstnih odtisov."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tipalo je začasno onemogočeno."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Tipala prstnih odtisov ni mogoče uporabiti. Obiščite ponudnika popravil."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Uporaba prstnega odtisa"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Uporaba prstnega odtisa ali odklepanja s poverilnico"</string>
@@ -2077,10 +2081,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 +2290,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KARTICA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 37092da..6e7c979 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kjo pajisje nuk ka sensor të gjurmës së gishtit."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensori është çaktivizuar përkohësisht."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Sensori i gjurmës së gishtit nuk mund të përdoret. Vizito një ofrues të shërbimit të riparimit"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Përdor gjurmën e gishtit"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Përdor gjurmën e gishtit ose kyçjen e ekranit"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KARTA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index a9cd089..f1fc5ca 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>
@@ -610,6 +612,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Овај уређај нема сензор за отисак прста."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензор је привремено онемогућен."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не можете да користите сензор за отисак прста. Посетите добављача за поправке"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користите отисак прста"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користите отисак прста или закључавање екрана"</string>
@@ -2285,4 +2289,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"КАРТИЦА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index c8d982d..3c96c56 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Enheten har ingen fingeravtryckssensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensorn har tillfälligt inaktiverats."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Det går inte att använda fingeravtryckssensorn. Besök ett reparationsställe"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Använd ditt fingeravtryck"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Använd ditt fingeravtryck eller skärmlåset"</string>
@@ -2075,10 +2079,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 +2271,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KORT <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 2d7ef7c..81ccc22 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kifaa hiki hakina kitambua alama ya kidole."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Kitambuzi kimezimwa kwa muda."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Imeshindwa kutumia kitambua alama ya kidole. Tembelea mtoa huduma za urekebishaji"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Kidole cha <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Tumia alama ya kidole"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Tumia alama ya kidole au mbinu ya kufunga skrini"</string>
@@ -2075,10 +2079,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"SIM KADI <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 5acfd93..b2836cb 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"இந்தச் சாதனத்தில் கைரேகை சென்சார் இல்லை."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"சென்சார் தற்காலிகமாக முடக்கப்பட்டுள்ளது."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"கைரேகை சென்சாரைப் பயன்படுத்த முடியவில்லை. பழுதுபார்ப்புச் சேவை வழங்குநரைத் தொடர்புகொள்ளவும்"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"கைரேகை <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"கைரேகையைப் பயன்படுத்து"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"கைரேகையையோ திரைப் பூட்டையோ பயன்படுத்து"</string>
@@ -2075,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>
@@ -2286,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"கார்டு <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 6882e3d..dbd8472 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -64,7 +64,7 @@
     <string name="CnirMmi" msgid="885292039284503036">"కాలింగ్ నంబర్ పరిమితం చేయబడింది"</string>
     <string name="ThreeWCMmi" msgid="2436550866139999411">"మూడు మార్గాల కాలింగ్"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"అవాంఛిత అంతరాయ కాల్స్‌ల తిరస్కరణ"</string>
-    <string name="CndMmi" msgid="185136449405618437">"కాలింగ్ నంబర్ బట్వాడా"</string>
+    <string name="CndMmi" msgid="185136449405618437">"కాలింగ్ నంబర్ డెలివరీ"</string>
     <string name="DndMmi" msgid="8797375819689129800">"అంతరాయం కలిగించవద్దు"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"కాలర్ ID ఆటోమేటిక్‌లపై పరిమితి ఉంటుంది. తర్వాత కాల్: పరిమితి ఉంటుంది"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"కాలర్ ID ఆటోమేటిక్‌లపై పరిమితి ఉంటుంది. తర్వాత కాల్: పరిమితి లేదు"</string>
@@ -319,7 +319,7 @@
     <string name="permgrouplab_phone" msgid="570318944091926620">"ఫోన్"</string>
     <string name="permgroupdesc_phone" msgid="270048070781478204">"ఫోన్ కాల్స్‌ చేయడం మరియు నిర్వహించడం"</string>
     <string name="permgrouplab_sensors" msgid="9134046949784064495">"శరీర సెన్సార్‌లు"</string>
-    <string name="permgroupdesc_sensors" msgid="2610631290633747752">"మీ అత్యంత కీలకమైన గుర్తుల గురించి సెన్సార్ డేటాని యాక్సెస్ చేస్తుంది"</string>
+    <string name="permgroupdesc_sensors" msgid="2610631290633747752">"మీ అత్యంత కీలకమైన గుర్తుల గురించి సెన్సార్ డేటాను యాక్సెస్ చేస్తుంది"</string>
     <string name="permgrouplab_notifications" msgid="5472972361980668884">"నోటిఫికేషన్‌లు"</string>
     <string name="permgroupdesc_notifications" msgid="4608679556801506580">"నోటిఫికేషన్‌లను చూపండి"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"విండో కంటెంట్‍ను తిరిగి పొందుతుంది"</string>
@@ -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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ఈ పరికరంలో వేలిముద్ర సెన్సార్ ఎంపిక లేదు."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"సెన్సార్ తాత్కాలికంగా డిజేబుల్ చేయబడింది."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"వేలిముద్ర సెన్సార్‌ను ఉపయోగించడం సాధ్యం కాదు. రిపెయిర్ ప్రొవైడర్‌ను సందర్శించండి"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"వేలు <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"వేలిముద్రను ఉపయోగించండి"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"వేలిముద్ర లేదా స్క్రీన్ లాక్‌ను ఉపయోగించండి"</string>
@@ -962,7 +966,7 @@
     <string name="lockscreen_glogin_submit_button" msgid="3590556636347843733">"సైన్ ఇన్ చేయండి"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="4369219936865697679">"వినియోగదారు పేరు లేదా పాస్‌వర్డ్ చెల్లదు."</string>
     <string name="lockscreen_glogin_account_recovery_hint" msgid="1683405808525090649">"మీ వినియోగదారు పేరు లేదా పాస్‌వర్డ్‌ను మర్చిపోయారా?\n"<b>"google.com/accounts/recovery"</b>"ని సందర్శించండి."</string>
-    <string name="lockscreen_glogin_checking_password" msgid="2607271802803381645">"తనిఖీ చేస్తోంది..."</string>
+    <string name="lockscreen_glogin_checking_password" msgid="2607271802803381645">"చెక్ చేస్తోంది..."</string>
     <string name="lockscreen_unlock_label" msgid="4648257878373307582">"అన్‌లాక్ చేయండి"</string>
     <string name="lockscreen_sound_on_label" msgid="1660281470535492430">"ధ్వని ఆన్‌లో ఉంది"</string>
     <string name="lockscreen_sound_off_label" msgid="2331496559245450053">"ధ్వని ఆఫ్‌లో ఉంది"</string>
@@ -1071,7 +1075,7 @@
     <string name="search_hint" msgid="455364685740251925">"సెర్చ్ చేయండి..."</string>
     <string name="searchview_description_search" msgid="1045552007537359343">"సెర్చ్"</string>
     <string name="searchview_description_query" msgid="7430242366971716338">"సెర్చ్ క్వెరీ"</string>
-    <string name="searchview_description_clear" msgid="1989371719192982900">"ప్రశ్నను క్లియర్ చేయి"</string>
+    <string name="searchview_description_clear" msgid="1989371719192982900">"ప్రశ్నను క్లియర్ చేయండి"</string>
     <string name="searchview_description_submit" msgid="6771060386117334686">"ప్రశ్నని సమర్పించండి"</string>
     <string name="searchview_description_voice" msgid="42360159504884679">"వాయిస్ సెర్చ్"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"తాకడం ద్వారా విశ్లేషణను ప్రారంభించాలా?"</string>
@@ -1126,17 +1130,17 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="8689459651807876423">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="2302144714803345056">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="1532369154488982046">"అన్నింటినీ ఎంచుకోండి"</string>
-    <string name="cut" msgid="2561199725874745819">"కత్తిరించు"</string>
+    <string name="cut" msgid="2561199725874745819">"కత్తిరించండి"</string>
     <string name="copy" msgid="5472512047143665218">"కాపీ చేయండి"</string>
     <string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"క్లిప్‌బోర్డ్‌కు కాపీ చేయడంలో విఫలమైంది"</string>
-    <string name="paste" msgid="461843306215520225">"అతికించు"</string>
-    <string name="paste_as_plain_text" msgid="7664800665823182587">"సాదా వచనం లాగా అతికించు"</string>
+    <string name="paste" msgid="461843306215520225">"పేస్ట్ చేయండి"</string>
+    <string name="paste_as_plain_text" msgid="7664800665823182587">"సాదా వచనం లాగా పేస్ట్ చేయండి"</string>
     <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="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>
@@ -1191,7 +1195,7 @@
     <string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"చిత్రాన్ని క్యాప్చర్ చేయి"</string>
     <string name="alwaysUse" msgid="3153558199076112903">"ఈ చర్యకు ఆటోమేటిక్‌గా ఉపయోగించండి."</string>
     <string name="use_a_different_app" msgid="4987790276170972776">"వేరొక యాప్‌ను ఉపయోగించండి"</string>
-    <string name="clearDefaultHintMsg" msgid="1325866337702524936">"సిస్టమ్ సెట్టింగ్‌లు &gt; యాప్‌లు &gt; డౌన్‌లోడ్ చేయబడినవిలో ఆటోమేటిక్‌ను క్లియర్ చేయి."</string>
+    <string name="clearDefaultHintMsg" msgid="1325866337702524936">"సిస్టమ్ సెట్టింగ్‌లు &gt; యాప్‌లు &gt; డౌన్‌లోడ్ చేయబడినవిలో ఆటోమేటిక్‌ను క్లియర్ చేయండి."</string>
     <string name="chooseActivity" msgid="8563390197659779956">"చర్యను ఎంచుకోండి"</string>
     <string name="chooseUsbActivity" msgid="2096269989990986612">"USB పరికరం కోసం యాప్‌ను ఎంచుకోండి"</string>
     <string name="noApplications" msgid="1186909265235544019">"ఈ చర్యను అమలు చేయగల యాప్‌లు ఏవీ లేవు."</string>
@@ -1321,7 +1325,7 @@
     <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">"మీరు దీన్ని తర్వాత సెట్టింగ్‌లు &gt; అనువర్తనాలులో మార్చవచ్చు"</string>
-    <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"ఎల్లప్పుడూ అనుమతించు"</string>
+    <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"ఎల్లప్పుడూ అనుమతించండి"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"ఎప్పటికీ అనుమతించవద్దు"</string>
     <string name="sim_removed_title" msgid="5387212933992546283">"సిమ్ కార్డు తీసివేయబడింది"</string>
     <string name="sim_removed_message" msgid="9051174064474904617">"మీరు చెల్లుబాటు అయ్యే సిమ్ కార్డు‌ను చొప్పించి పునఃప్రారంభించే వరకు మొబైల్ నెట్‌వర్క్ అందుబాటులో ఉండదు."</string>
@@ -1329,7 +1333,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>
@@ -1364,7 +1368,7 @@
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"పరీక్ష నియంత్రణ మోడ్ ప్రారంభించబడింది"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"పరీక్ష నియంత్రణ మోడ్‌ను నిలిపివేయడానికి ఫ్యాక్టరీ రీసెట్‍‌ను అమలు చేయండి."</string>
     <string name="console_running_notification_title" msgid="6087888939261635904">"సీరియల్ కన్సోల్ ప్రారంభించబడింది"</string>
-    <string name="console_running_notification_message" msgid="7892751888125174039">"పని తీరు ప్రభావితమైంది. నిలిపివేయడానికి, బూట్‌లోడర్‌ను తనిఖీ చేయండి."</string>
+    <string name="console_running_notification_message" msgid="7892751888125174039">"పని తీరు ప్రభావితమైంది. నిలిపివేయడానికి, బూట్‌లోడర్‌ను చెక్ చేయండి."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"ప్రయోగాత్మక MTE ఎనేబుల్ చేయబడింది"</string>
     <string name="mte_override_notification_message" msgid="2441170442725738942">"పనితీరు, స్థిరత్వం ప్రభావితం కావచ్చు. డిజేబుల్ చేయడానికి రీబూట్ చేయండి. arm64.memtag.bootctlని ఉపయోగించి ఎనేబుల్ చేసినట్లయితే, దాన్ని ముందుగా ఏదీ లేనిదిగా సెట్ చేయండి."</string>
     <string name="usb_contaminant_detected_title" msgid="4359048603069159678">"USB పోర్ట్‌లో ద్రవ లేదా వ్యర్థ పదార్థాలు ఉన్నాయి"</string>
@@ -1378,7 +1382,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>
@@ -1389,7 +1393,7 @@
     <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> ఇతర యాప్‌లలో చూపబడుతోంది"</string>
     <string name="alert_windows_notification_message" msgid="6538171456970725333">"<xliff:g id="NAME">%s</xliff:g> ఈ లక్షణాన్ని ఉపయోగించకూడదు అని మీరు అనుకుంటే, సెట్టింగ్‌లను తెరవడానికి ట్యాప్ చేసి, దీన్ని ఆఫ్ చేయండి."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"ఆఫ్ చేయి"</string>
-    <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g>ని తనిఖీ చేస్తోంది…"</string>
+    <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g>ని చెక్ చేస్తోంది…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"ప్రస్తుత కంటెంట్ సమీక్షించబడుతోంది"</string>
     <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"మీడియా స్టోరేజ్‌ను విశ్లేషిస్తోంది"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"కొత్త <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1429,7 +1433,7 @@
     <string name="ext_media_move_failure_message" msgid="4197306718121869335">"కంటెంట్‌ని తరలించడానికి మళ్లీ ప్రయత్నించండి"</string>
     <string name="ext_media_status_removed" msgid="241223931135751691">"తీసివేయబడింది"</string>
     <string name="ext_media_status_unmounted" msgid="8145812017295835941">"తొలగించబడింది"</string>
-    <string name="ext_media_status_checking" msgid="159013362442090347">"తనిఖీ చేస్తోంది..."</string>
+    <string name="ext_media_status_checking" msgid="159013362442090347">"చెక్ చేస్తోంది..."</string>
     <string name="ext_media_status_mounted" msgid="3459448555811203459">"సిద్ధంగా ఉంది"</string>
     <string name="ext_media_status_mounted_ro" msgid="1974809199760086956">"చదవడానికి మాత్రమే"</string>
     <string name="ext_media_status_bad_removal" msgid="508448566481406245">"అసురక్షితంగా తీసివేయబడింది"</string>
@@ -1576,8 +1580,8 @@
     <string name="data_usage_restricted_title" msgid="126711424380051268">"నేపథ్య డేటా పరిమితం చేయబడింది"</string>
     <string name="data_usage_restricted_body" msgid="5338694433686077733">"నియంత్రణ తీసివేయడానికి నొక్కండి."</string>
     <string name="data_usage_rapid_title" msgid="2950192123248740375">"అధిక మొబైల్ డేటా వినియోగం"</string>
-    <string name="data_usage_rapid_body" msgid="3886676853263693432">"మీ యాప్‌లు సాధారణం కంటే ఎక్కువ డేటాని ఉపయోగించాయి"</string>
-    <string name="data_usage_rapid_app_body" msgid="5425779218506513861">"<xliff:g id="APP">%s</xliff:g> సాధారణం కంటే ఎక్కువ డేటాని ఉపయోగించింది"</string>
+    <string name="data_usage_rapid_body" msgid="3886676853263693432">"మీ యాప్‌లు సాధారణం కంటే ఎక్కువ డేటాను ఉపయోగించాయి"</string>
+    <string name="data_usage_rapid_app_body" msgid="5425779218506513861">"<xliff:g id="APP">%s</xliff:g> సాధారణం కంటే ఎక్కువ డేటాను ఉపయోగించింది"</string>
     <string name="ssl_certificate" msgid="5690020361307261997">"సెక్యూరిటీ సర్టిఫికెట్"</string>
     <string name="ssl_certificate_is_valid" msgid="7293675884598527081">"ఈ సర్టిఫికెట్ చెల్లుబాటు అవుతుంది."</string>
     <string name="issued_to" msgid="5975877665505297662">"దీనికి జారీ చేయబడింది:"</string>
@@ -1642,7 +1646,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>
@@ -1651,7 +1655,7 @@
     <string name="kg_login_submit_button" msgid="893611277617096870">"సైన్ ఇన్ చేయండి"</string>
     <string name="kg_login_invalid_input" msgid="8292367491901220210">"చెల్లని వినియోగదారు పేరు లేదా పాస్‌వర్డ్."</string>
     <string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"మీ వినియోగదారు పేరు లేదా పాస్‌వర్డ్‌ను మర్చిపోయారా?\n"<b>"google.com/accounts/recovery"</b>"ని సందర్శించండి."</string>
-    <string name="kg_login_checking_password" msgid="4676010303243317253">"ఖాతాను తనిఖీ చేస్తోంది…"</string>
+    <string name="kg_login_checking_password" msgid="4676010303243317253">"ఖాతాను చెక్ చేస్తోంది…"</string>
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"మీరు మీ పిన్‌ను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా టైప్ చేశారు. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"మీరు మీ పాస్‌వర్డ్‌ను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా టైప్ చేశారు. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"మీరు మీ అన్‌లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీసారు. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
@@ -1665,7 +1669,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"మీరు మీ అన్‌లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీశారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> విఫల ప్రయత్నాల తర్వాత మీ Android TV పరికరాన్ని ఈమెయిల్‌ ఖాతా ద్వారా అన్‌లాక్ చేయాల్సిందిగా మిమ్మల్ని కోరడం జరుగుతుంది.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"మీరు మీ అన్‌లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> విఫల ప్రయత్నాల తర్వాత, ఈమెయిల్‌ ఖాతాను ఉపయోగించి మీ ఫోన్‌ను అన్‌లాక్ చేయాల్సిందిగా మిమ్మల్ని అడుగుతారు.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
-    <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"తీసివేయి"</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"తీసివేయండి"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"వాల్యూమ్‌ను సిఫార్సు చేయబడిన స్థాయి కంటే ఎక్కువగా పెంచాలా?\n\nసుదీర్ఘ వ్యవధుల పాటు అధిక వాల్యూమ్‌లో వినడం వలన మీ వినికిడి శక్తి దెబ్బ తినవచ్చు."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"యాక్సెస్ సామర్థ్యం షార్ట్‌కట్‌ను ఉపయోగించాలా?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"షార్ట్‌కట్ ఆన్ చేసి ఉన్నప్పుడు, రెండు వాల్యూమ్ బటన్‌లను 3 సెకన్ల పాటు నొక్కి ఉంచితే యాక్సెస్ సౌలభ్య ఫీచర్ ప్రారంభం అవుతుంది."</string>
@@ -1684,7 +1688,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>
@@ -1950,7 +1954,7 @@
     <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"ఈ యాప్ అదనపు సెక్యూరిటీ కోసం రిక్వెస్ట్ చేస్తోంది. బదులుగా మీ Android TV పరికరంలో ట్రై చేయండి."</string>
     <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"ఈ యాప్ అదనపు సెక్యూరిటీ కోసం రిక్వెస్ట్ చేస్తోంది. బదులుగా మీ టాబ్లెట్‌లో ట్రై చేయండి."</string>
     <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"ఈ యాప్ అదనపు సెక్యూరిటీ కోసం రిక్వెస్ట్ చేస్తోంది. బదులుగా మీ ఫోన్‌లో ట్రై చేయండి."</string>
-    <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ఈ యాప్ పాత వెర్షన్ Android కోసం రూపొందించబడింది మరియు అది సరిగ్గా పని చేయకపోవచ్చు. అప్‌డేట్‌ల కోసం తనిఖీ చేయడానికి ప్రయత్నించండి లేదా డెవలపర్‌ని సంప్రదించండి."</string>
+    <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ఈ యాప్ పాత వెర్షన్ Android కోసం రూపొందించబడింది మరియు అది సరిగ్గా పని చేయకపోవచ్చు. అప్‌డేట్‌ల కోసం చెక్ చేయడానికి ప్రయత్నించండి లేదా డెవలపర్‌ని సంప్రదించండి."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"అప్‌డేట్ కోసం చెక్ చేయండి"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"మీకు కొత్త మెసేజ్‌లు ఉన్నాయి"</string>
     <string name="new_sms_notification_content" msgid="3197949934153460639">"వీక్షించడానికి SMS యాప్‌ను తెరవండి"</string>
@@ -1972,7 +1976,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>
@@ -2053,7 +2057,7 @@
     <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"కొత్తది: అంతరాయం కలిగించవద్దు నోటిఫికేషన్‌లను దాస్తోంది"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"మరింత తెలుసుకోవడానికి మరియు మార్చడానికి నొక్కండి."</string>
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"అంతరాయం కలిగించవద్దు మార్చబడింది"</string>
-    <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"బ్లాక్ చేయబడిన దాన్ని తనిఖీ చేయడానికి నొక్కండి."</string>
+    <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"బ్లాక్ చేయబడిన దాన్ని చెక్ చేయడానికి నొక్కండి."</string>
     <string name="review_notification_settings_title" msgid="5102557424459810820">"నోటిఫికేషన్ సెట్టింగ్‌లను రివ్యూ చేయండి"</string>
     <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13తో మొదలుకుని, మీరు ఇన్‌స్టాల్ చేసే యాప్‌లకు నోటిఫికేషన్‌లను పంపడానికి మీ అనుమతి అవసరం. ఇప్పటికే ఉన్న యాప్‌ల కోసం ఈ అనుమతిని మార్చడానికి ట్యాప్ చేయండి."</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"తర్వాత గుర్తు చేయి"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"కార్డ్ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 34d2dbf..66d85d0 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"อุปกรณ์นี้ไม่มีเซ็นเซอร์ลายนิ้วมือ"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ปิดใช้เซ็นเซอร์ชั่วคราวแล้ว"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ใช้เซ็นเซอร์ลายนิ้วมือไม่ได้ โปรดติดต่อผู้ให้บริการซ่อม"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"นิ้ว <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ใช้ลายนิ้วมือ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ใช้ลายนิ้วมือหรือการล็อกหน้าจอ"</string>
@@ -2075,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 ใน 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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"ซิมการ์ด <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 21c18be..543b0aa 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Walang sensor ng fingerprint ang device na ito."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Pansamantalang na-disable ang sensor."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Hindi magamit ang sensor para sa fingerprint. Bumisita sa provider ng pag-aayos"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Daliri <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gumamit ng fingerprint"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gumamit ng fingerprint o lock ng screen"</string>
@@ -2075,10 +2079,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"CARD <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 29e6811..fd07f89 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda parmak izi sensörü yok."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensör geçici olarak devre dışı bırakıldı."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Parmak izi sensörü kullanılamıyor. Bir onarım hizmeti sağlayıcıyı ziyaret edin"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. parmak"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Parmak izi kullan"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Parmak izi veya ekran kilidi kullan"</string>
@@ -2075,10 +2079,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"KART <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 72b90b2..4fad265 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>
@@ -611,6 +613,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На цьому пристрої немає сканера відбитків пальців."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик тимчасово вимкнено."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не вдається скористатися сканером відбитків пальців. Зверніться до постачальника послуг із ремонту."</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Відбиток пальця <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Доступ за відбитком пальця"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Використовувати відбиток пальця або дані для розблокування екрана"</string>
@@ -638,8 +642,8 @@
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Тримайте телефон ближче до обличчя"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Підніміть телефон вище"</string>
     <string name="face_acquired_too_low" msgid="4075391872960840081">"Опустіть телефон нижче"</string>
-    <string name="face_acquired_too_right" msgid="6245286514593540859">"Тримайте телефон лівіше"</string>
-    <string name="face_acquired_too_left" msgid="9201762240918405486">"Тримайте телефон правіше"</string>
+    <string name="face_acquired_too_right" msgid="6245286514593540859">"Посуньте телефон лівіше"</string>
+    <string name="face_acquired_too_left" msgid="9201762240918405486">"Посуньте телефон правіше"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Дивіться просто на пристрій."</string>
     <string name="face_acquired_not_detected" msgid="1057966913397548150">"Обличчя не видно. Утримуйте телефон на рівні очей."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Забагато рухів. Тримайте телефон нерухомо."</string>
@@ -2077,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>
@@ -2288,4 +2290,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"КАРТКА <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 221c5b0..6caff71 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"اس آلہ میں فنگر پرنٹ سینسر نہیں ہے۔"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"سینسر عارضی طور غیر فعال ہے۔"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"فنگر پرنٹ سینسر کا استعمال نہیں کر سکتے۔ ایک مرمت فراہم کنندہ کو ملاحظہ کریں"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"فنگر پرنٹ استعمال کریں"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"فنگر پرنٹ یا اسکرین لاک استعمال کریں"</string>
@@ -2075,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>
@@ -2286,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"کارڈ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 8cba718..2d420b1 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu qurilmada barmoq izi skaneri mavjud emas."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor vaqtincha faol emas."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Barmoq izi skaneridan foydalanish imkonsiz. Xizmat koʻrsatish markaziga murojaat qiling"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Barmoq izi <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmoq izi ishlatish"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Barmoq izi yoki ekran qulfi"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"SIM KARTA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index ce0b715..bef3329 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Thiết bị này không có cảm biến vân tay."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Đã tạm thời tắt cảm biến."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Không thể dùng cảm biến vân tay. Hãy liên hệ với một nhà cung cấp dịch vụ sửa chữa"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Ngón tay <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Dùng vân tay"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Dùng vân tay hoặc phương thức khóa màn hình"</string>
@@ -652,7 +656,7 @@
     <string name="face_acquired_dark_glasses_detected" msgid="7263638432128692048">"Bạn cần cho thấy toàn bộ khuôn mặt của mình"</string>
     <string name="face_acquired_mouth_covering_detected" msgid="615991670821926847">"Toàn bộ khuôn mặt của bạn phải được hiển thị"</string>
     <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Không thể tạo mẫu khuôn mặt của bạn. Hãy thử lại."</string>
-    <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Đã phát hiện đeo kính đen. Toàn bộ khuôn mặt của bạn phải được hiển thị."</string>
+    <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Đã phát hiện thấy kính râm. Toàn bộ khuôn mặt của bạn phải được trông thấy rõ ràng."</string>
     <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Đã phát hiện khuôn mặt bị che khuất. Toàn bộ khuôn mặt của bạn phải được hiển thị."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
@@ -2076,7 +2080,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 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"THẺ <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 4257f78..8da18dc3 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此设备没有指纹传感器。"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"传感器已暂时停用。"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"无法使用指纹传感器。请联系维修服务提供商"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指纹"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指纹或屏幕锁定凭据"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"SIM 卡 <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 6374db5..0c4d8f8 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此裝置沒有指紋感應器。"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"無法使用指紋感應器。請諮詢維修服務供應商"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋鎖定"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"SIM 卡 <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index aaa05f0..20a941f 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"這個裝置沒有指紋感應器。"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"指紋感應器無法使用,請洽詢維修供應商"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定功能"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"SIM 卡 <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 20b8b58..36725e9 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>
@@ -609,6 +611,8 @@
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Le divayisi ayinayo inzwa yezigxivizo zeminwe."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Inzwa ikhutshazwe okwesikhashana."</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ayikwazi ukusebenzisa inzwa yesigxivizo somunwe. Vakashela umhlinzeki wokulungisa"</string>
+    <!-- no translation found for fingerprint_error_power_pressed (5479524500542129414) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Umunwe ongu-<xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Sebenzisa izigxivizo zeminwe"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Sebenzisa izigxivizo zeminwe noma ukukhiya isikrini"</string>
@@ -2284,4 +2288,5 @@
     <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>
+    <string name="default_card_name" msgid="9198284935962911468">"IKHADI <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 2876161..9d2c3d7 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -757,6 +757,15 @@
          bar for all apps. -->
     <bool name="config_remoteInsetsControllerControlsSystemBars">false</bool>
 
+    <!-- Control whether the system bars can be requested when using a remote insets control target.
+         This allows for specifying whether or not system bars can be shown by the user (via swipe
+         or other means) when they are hidden by the logic defined by the remote insets controller.
+         This is useful for cases where the system provides alternative affordances for showing and
+         hiding the bars or for cases in which it's desired the bars not be shown for any reason.
+         This configuration will only apply when config_remoteInsetsControllerControlsSystemBars.
+         is set to true. -->
+    <bool name="config_remoteInsetsControllerSystemBarsCanBeShownByUserAction">false</bool>
+
     <!-- HDMI behavior -->
 
     <!-- The number of degrees to rotate the display when the device has HDMI connected
@@ -2308,18 +2317,26 @@
          it should be disabled in that locale's resources. -->
     <bool name="config_actionMenuItemAllCaps">true</bool>
 
-    <!-- Remote server that can provide NTP responses. -->
-    <string translatable="false" name="config_ntpServer">time.android.com</string>
-    <!-- Normal polling frequency in milliseconds -->
-    <integer name="config_ntpPollingInterval">64800000</integer>
-    <!-- Try-again polling interval in milliseconds, in case the network request failed -->
-    <integer name="config_ntpPollingIntervalShorter">60000</integer>
-    <!-- Number of times to try again with the shorter interval, before backing
-         off until the normal polling interval. A value < 0 indicates infinite. -->
-    <integer name="config_ntpRetry">3</integer>
-    <!-- Timeout to wait for NTP server response in milliseconds. -->
+    <!-- SNTP client config: NTP servers to use to obtain an accurate time.
+         Items must be in the form: "ntp://<host>[:port]"
+         This is not a registered IANA URI scheme. -->
+    <string-array translatable="false" name="config_ntpServers">
+        <item>ntp://time.android.com</item>
+    </string-array>
+    <!-- SNTP client config: Timeout to wait for an NTP server response in milliseconds. -->
     <integer name="config_ntpTimeout">5000</integer>
 
+    <!-- Automatic "network" time detection config: Normal network time polling frequency in
+         milliseconds. -->
+    <integer name="config_ntpPollingInterval">64800000</integer>
+    <!-- Automatic "network" time detection config: Try-again network time polling interval in
+         milliseconds, in case the network request failed -->
+    <integer name="config_ntpPollingIntervalShorter">60000</integer>
+    <!-- Automatic "network" time detection config: Number of times to try network time polling with
+         the shorter interval, before backing off until the normal polling interval. A value < 0
+         indicates infinite. -->
+    <integer name="config_ntpRetry">3</integer>
+
     <!-- Default network policy warning threshold, in megabytes. -->
     <integer name="config_networkPolicyDefaultWarning">2048</integer>
 
@@ -3459,6 +3476,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/strings.xml b/core/res/res/values/strings.xml
index aef71e43..d3dc301 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>
@@ -1831,9 +1833,9 @@
     <!-- Message shown during acquisition when the sensor is dirty [CHAR LIMIT=100] -->
     <string name="face_acquired_sensor_dirty">Clean the top of your screen, including the black bar</string>
     <!-- Message shown during acquisition when dark glasses were detected [CHAR LIMIT=75] -->
-    <string name="face_acquired_dark_glasses_detected">Your face must be fully visible</string>
+    <string name="face_acquired_dark_glasses_detected">@string/face_acquired_dark_glasses_detected_alt</string>
     <!-- Message shown during acquisition when a mouth covering was detected [CHAR LIMIT=75] -->
-    <string name="face_acquired_mouth_covering_detected">Your face must be fully visible</string>
+    <string name="face_acquired_mouth_covering_detected">@string/face_acquired_mouth_covering_detected_alt</string>
 
     <!-- Message shown during face acquisition when the sensor needs to be recalibrated [CHAR LIMIT=75] -->
     <string name="face_acquired_recalibrate_alt">Can\u2019t create your face model. Try again.</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/styles_car.xml b/core/res/res/values/styles_car.xml
index ca3ba93..0655fde 100644
--- a/core/res/res/values/styles_car.xml
+++ b/core/res/res/values/styles_car.xml
@@ -14,96 +14,15 @@
      limitations under the License.
 -->
 <resources>
-    <!-- Car text -->
-    <style name="CarBody1">
-        <item name="textStyle">normal</item>
-        <item name="textSize">@dimen/car_body1_size</item>
-        <item name="textColor">@color/car_body1</item>
-    </style>
-
-    <style name="CarBody1.Light">
-        <item name="textColor">@color/car_body1_light</item>
-    </style>
-
-    <style name="CarBody1.Dark">
-        <item name="textColor">@color/car_body2_dark</item>
-    </style>
-
-    <style name="CarBody2">
-        <item name="textStyle">normal</item>
-        <item name="textSize">@dimen/car_body2_size</item>
-        <item name="textColor">@color/car_body2</item>
-    </style>
-
-    <style name="CarBody2.Dark">
-        <item name="textColor">@color/car_body2_dark</item>
-    </style>
-    <style name="CarBody2.Light">
-        <item name="textColor">@color/car_body2_light</item>
-    </style>
-
-    <style name="CarBody3">
-        <item name="textStyle">normal</item>
-        <item name="textSize">@dimen/car_body3_size</item>
-        <item name="textColor">@color/car_body3</item>
-    </style>
-
-    <!-- The smallest styling for body text. The color of this text changes based on the day/night
-         mode. -->
-    <style name="CarBody4">
+    <!-- The Dialog message text style-->
+    <style name="CarDialogMessageText">
         <item name="textStyle">normal</item>
         <item name="textSize">@dimen/car_body4_size</item>
         <item name="textColor">@color/car_body4</item>
     </style>
-
-    <style name="CarAction1">
-        <item name="textStyle">bold</item>
-        <item name="textSize">@dimen/car_action1_size</item>
-        <item name="textColor">@color/control_default_material</item>
-    </style>
-
-    <style name="CarAction1.Dark">
-        <item name="textColor">@color/car_highlight_dark</item>
-    </style>
-    <style name="CarAction1.Light">
-        <item name="textColor">@color/car_highlight_light</item>
-    </style>
-
-    <!-- The styling for title text. The color of this text changes based on day/night mode. -->
-    <style name="CarTitle" >
-        <item name="textStyle">bold</item>
-        <item name="textSize">@dimen/car_title2_size</item>
-        <item name="textColor">@color/car_title</item>
-    </style>
-
-    <!-- Title text that is permanently a dark color. -->
-    <style name="CarTitle.Dark" >
-        <item name="textColor">@color/car_title_dark</item>
-    </style>
-
-    <!-- Title text that is permanently a light color. -->
-    <style name="CarTitle.Light" >
-        <item name="textColor">@color/car_title_light</item>
-    </style>
-
-    <!-- Action bar -->
-    <style name="ActionBarTitle" parent="@style/Widget.DeviceDefault.TextView">
-        <item name="android:singleLine">true</item>
-        <item name="android:textAppearance">?attr/textAppearanceLarge</item>
-    </style>
-
-    <style name="ActionBarButton"
-           parent="@style/Widget.DeviceDefault.Button.Borderless.Colored">
-        <item name="android:textAppearance">@style/ActionBarButtonTextAppearance</item>
-        <!-- Button's internal horizontal padding -->
-        <item name="android:paddingStart">@*android:dimen/car_padding_3</item>
-        <item name="android:paddingEnd">@*android:dimen/car_padding_3</item>
-        <item name="android:drawablePadding">@*android:dimen/car_padding_2</item>
-        <item name="android:maxWidth">@*android:dimen/action_bar_button_max_width</item>
-    </style>
-
-    <style name="ActionBarButtonTextAppearance"
-           parent="@style/TextAppearance.DeviceDefault.Widget.Button.Borderless.Colored">
-        <item name="android:textAllCaps">false</item>
+    <!-- This style makes Dialog button text use medium font weight.  -->
+    <style name="CarDialogButtonText">
+        <item name="android:textAppearance">@style/TextAppearance.DeviceDefault.Widget.Button</item>
+        <item name="android:textColor">@color/control_default_material</item>
     </style>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b7c3839..bcf9759 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -697,7 +697,7 @@
   <java-symbol type="string" name="config_forceVoiceInteractionServicePackage" />
   <java-symbol type="string" name="config_mms_user_agent" />
   <java-symbol type="string" name="config_mms_user_agent_profile_url" />
-  <java-symbol type="string" name="config_ntpServer" />
+  <java-symbol type="array" name="config_ntpServers" />
   <java-symbol type="string" name="config_useragentprofile_url" />
   <java-symbol type="string" name="config_appsNotReportingCrashes" />
   <java-symbol type="string" name="contentServiceSync" />
@@ -1569,6 +1569,7 @@
   <java-symbol type="layout" name="time_picker_dialog" />
   <java-symbol type="layout" name="tooltip" />
   <java-symbol type="layout" name="transient_notification" />
+  <java-symbol type="layout" name="transient_notification_with_icon" />
   <java-symbol type="layout" name="voice_interaction_session" />
   <java-symbol type="layout" name="web_text_view_dropdown" />
   <java-symbol type="layout" name="webview_find" />
@@ -1726,6 +1727,7 @@
   <java-symbol type="bool" name="config_enableLockBeforeUnlockScreen" />
   <java-symbol type="bool" name="config_enableLockScreenRotation" />
   <java-symbol type="bool" name="config_remoteInsetsControllerControlsSystemBars" />
+  <java-symbol type="bool" name="config_remoteInsetsControllerSystemBarsCanBeShownByUserAction" />
   <java-symbol type="bool" name="config_lidControlsScreenLock" />
   <java-symbol type="bool" name="config_lidControlsSleep" />
   <java-symbol type="bool" name="config_lockDayNightMode" />
@@ -2616,10 +2618,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 +4821,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/batterystatstests/BatteryStatsViewer/AndroidManifest.xml b/core/tests/batterystatstests/BatteryStatsViewer/AndroidManifest.xml
index 6639c02..6e9d4db 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/AndroidManifest.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/AndroidManifest.xml
@@ -21,6 +21,7 @@
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
     <uses-permission android:name="android.permission.BATTERY_STATS"/>
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
+    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
 
     <application
         android:theme="@style/Theme"
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/NtpTrustedTimeTest.java b/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java
new file mode 100644
index 0000000..4de27c3
--- /dev/null
+++ b/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java
@@ -0,0 +1,639 @@
+/*
+ * 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.util;
+
+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.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.when;
+
+import static java.lang.String.join;
+import static java.util.Arrays.asList;
+
+import android.net.Network;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mockito;
+
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.time.Duration;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NtpTrustedTimeTest {
+
+    private static final Duration VALID_TIMEOUT = Duration.ofSeconds(5);
+
+    // Valid absolute URIs, but not ones that will be accepted as NTP server URIs.
+    private static final List<String> BAD_ABSOLUTE_NTP_URIS = asList(
+            "ntp://:123/",
+            "ntp://:123",
+            "ntp://:/",
+            "ntp://:",
+            "ntp://foobar:abc/",
+            "ntp://foobar:abc",
+            "ntp://foobar:456:789/",
+            "ntp://foobar:456:789",
+            "ntp://foobar:456:abc/",
+            "ntp://foobar:456:abc"
+    );
+
+    // Valid relative URIs, but not ones that will be accepted as NTP server URIs.
+    private static final List<String> BAD_RELATIVE_NTP_URIS = asList(
+            "foobar",
+            "/foobar",
+            "foobar:456"
+    );
+
+    // Valid NTP server URIs: A pair of {input value} -> {expected URI.toString()} value.
+    private static final List<Pair<String, String>> GOOD_NTP_URIS = asList(
+            identityPair("ntp://foobar"),
+            identityPair("ntp://foobar/"),
+            identityPair("ntp://foobar:456/"),
+            identityPair("ntp://foobar:456")
+    );
+
+    private static final List<URI> VALID_SERVER_URIS = createUris("ntp://foobar/");
+
+    @Test
+    public void testParseNtpServerSetting() {
+        // Valid legacy settings single value.
+        assertEquals(createUris("ntp://foobar"), NtpTrustedTime.parseNtpServerSetting("foobar"));
+
+        // Legacy settings values which could easily be confused with relative URIs. Parsing of this
+        // legacy form doesn't have to be robust / treated as errors: Android has never supported
+        // string like these, and so they won't work properly.
+        assertNull(NtpTrustedTime.parseNtpServerSetting("foobar:123"));
+        assertNull(NtpTrustedTime.parseNtpServerSetting("/foobar"));
+
+        // NTP URI cases that must not be accepted.
+        for (String badNtpUri : BAD_ABSOLUTE_NTP_URIS) {
+            assertNull("Input: \"" + badNtpUri + "\"",
+                    NtpTrustedTime.parseNtpServerSetting(badNtpUri));
+        }
+
+        // Valid single NTP URIs.
+        for (Pair<String, String> goodNtpUri : GOOD_NTP_URIS) {
+            List<URI> uris = NtpTrustedTime.parseNtpServerSetting(goodNtpUri.first);
+            assertNotNull(uris);
+            assertEquals(1, uris.size());
+            URI actualUri = uris.get(0);
+            assertNotNull(goodNtpUri.first, actualUri);
+            assertEquals(goodNtpUri.second, actualUri.toString());
+        }
+
+        // Valid multi-server name value. Not historically supported, but it's easier to support
+        // this than rule it out.
+        final String multiSettingDelimiter = NtpTrustedTime.NTP_SETTING_SERVER_NAME_DELIMITER;
+        String validMultiServerNameSetting = join(multiSettingDelimiter, "foobar", "barbaz");
+        List<URI> expectedMultiServerNameUris = createUris("ntp://foobar", "ntp://barbaz");
+        assertParseNtpServerSettingResult(expectedMultiServerNameUris, validMultiServerNameSetting);
+
+        // Any invalid values should result in a null return value.
+        String invalidServerName = "foobar:123";
+        assertNull(NtpTrustedTime.parseNtpServerSetting(
+                join(multiSettingDelimiter, validMultiServerNameSetting, invalidServerName)));
+        assertNull(NtpTrustedTime.parseNtpServerSetting(
+                join(multiSettingDelimiter, invalidServerName, validMultiServerNameSetting)));
+
+        // Valid multi-NTP URL string.
+        Pair<String, String> goodNtpUri1 = GOOD_NTP_URIS.get(0);
+        Pair<String, String> goodNtpUri2 = GOOD_NTP_URIS.get(1);
+        String validMultiNtpUriSetting =
+                join(multiSettingDelimiter, goodNtpUri1.first, goodNtpUri2.first);
+        List<URI> expectedMultiNtpUris = createUris(goodNtpUri1.second, goodNtpUri2.second);
+        assertParseNtpServerSettingResult(expectedMultiNtpUris, validMultiNtpUriSetting);
+
+        // Valid string containing both old and new settings forms.
+        String validCombinedMultiNtpSetting =
+                join(multiSettingDelimiter, validMultiNtpUriSetting, validMultiServerNameSetting);
+        List<URI> expectedCombinedNtpUris =
+                Stream.concat(expectedMultiNtpUris.stream(), expectedMultiServerNameUris.stream())
+                        .collect(Collectors.toList());
+        assertParseNtpServerSettingResult(expectedCombinedNtpUris, validCombinedMultiNtpSetting);
+    }
+
+    private static void assertParseNtpServerSettingResult(
+            List<URI> expectedUris, String settingsString) {
+        assertEquals("Input: " + settingsString, expectedUris,
+                NtpTrustedTime.parseNtpServerSetting(settingsString));
+    }
+
+    @Test
+    public void testParseNtpUriStrict() throws Exception {
+        // ntp: URI cases that must not be accepted.
+        for (String badNtpUri : BAD_ABSOLUTE_NTP_URIS) {
+            assertParseNtpUriStrictThrows(badNtpUri);
+        }
+
+        for (String badNtpUri : BAD_RELATIVE_NTP_URIS) {
+            assertParseNtpUriStrictThrows(badNtpUri);
+        }
+
+        // Bad scheme.
+        assertParseNtpUriStrictThrows("notntp://foobar:123");
+
+        // Valid NTP URIs
+        for (Pair<String, String> goodNtpUri : GOOD_NTP_URIS) {
+            URI uri = NtpTrustedTime.parseNtpUriStrict(goodNtpUri.first);
+            assertNotNull(goodNtpUri.first, uri);
+            assertEquals(goodNtpUri.second, uri.toString());
+        }
+    }
+
+    private void assertParseNtpUriStrictThrows(String badNtpUri) throws Exception {
+        assertThrows("Input: \"" + badNtpUri, URISyntaxException.class,
+                () -> NtpTrustedTime.parseNtpUriStrict(badNtpUri));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testNtpConfig_nullConstructorServerInfo() {
+        new NtpTrustedTime.NtpConfig(null, Duration.ofSeconds(5));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testNtpConfig_nullConstructorTimeout() {
+        new NtpTrustedTime.NtpConfig(VALID_SERVER_URIS, null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testNtpConfig_zeroTimeout() {
+        new NtpTrustedTime.NtpConfig(VALID_SERVER_URIS, Duration.ofMillis(0));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testNtpConfig_negativeTimeout() {
+        new NtpTrustedTime.NtpConfig(VALID_SERVER_URIS, Duration.ofMillis(-1));
+    }
+
+    @Test
+    public void testForceRefreshDefaultNetwork_noConnectivity() {
+        NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+        Network network = mock(Network.class);
+        when(ntpTrustedTime.getDefaultNetwork()).thenReturn(network);
+        when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(false);
+
+        assertFalse(ntpTrustedTime.forceRefresh());
+
+        InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+        inOrder.verify(ntpTrustedTime, times(1)).getDefaultNetwork();
+        inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
+        inOrder.verifyNoMoreInteractions();
+
+        assertNoCachedTimeValueResult(ntpTrustedTime);
+    }
+
+    @Test
+    public void testForceRefreshDefaultNetwork_noActiveNetwork() {
+        NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+        when(ntpTrustedTime.getDefaultNetwork()).thenReturn(null);
+
+        assertFalse(ntpTrustedTime.forceRefresh());
+
+        InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+        inOrder.verify(ntpTrustedTime, times(1)).getDefaultNetwork();
+        inOrder.verifyNoMoreInteractions();
+
+        assertNoCachedTimeValueResult(ntpTrustedTime);
+    }
+
+    @Test
+    public void testForceRefreshDefaultNetwork_nullConfig() {
+        NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+        Network network = mock(Network.class);
+        when(ntpTrustedTime.getDefaultNetwork()).thenReturn(network);
+        when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
+        when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(null);
+
+        assertFalse(ntpTrustedTime.forceRefresh());
+
+        InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+        inOrder.verify(ntpTrustedTime, times(1)).getDefaultNetwork();
+        inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
+        inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+        inOrder.verifyNoMoreInteractions();
+
+        assertNoCachedTimeValueResult(ntpTrustedTime);
+    }
+
+    @Test
+    public void testForceRefresh_nullConfig() {
+        NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+        Network network = mock(Network.class);
+        when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
+        when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(null);
+
+        assertFalse(ntpTrustedTime.forceRefresh(network));
+
+        InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+        inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
+        inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+        inOrder.verifyNoMoreInteractions();
+
+        assertNoCachedTimeValueResult(ntpTrustedTime);
+    }
+
+    @Test
+    public void testForceRefresh_noConnectivity() {
+        NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+        Network network = mock(Network.class);
+        when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(false);
+
+        assertFalse(ntpTrustedTime.forceRefresh(network));
+
+        InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+        inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
+        inOrder.verifyNoMoreInteractions();
+
+        assertNoCachedTimeValueResult(ntpTrustedTime);
+    }
+
+    @Test
+    public void testForceRefresh_singleServer_queryFailed() {
+        NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+        Network network = mock(Network.class);
+        when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
+        List<URI> serverUris = createUris("ntp://ntpserver.name");
+        when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
+                new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
+        when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
+                .thenReturn(null);
+
+        assertFalse(ntpTrustedTime.forceRefresh(network));
+
+        InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+        inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
+        inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+        inOrder.verify(ntpTrustedTime, times(1))
+                .queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
+        inOrder.verifyNoMoreInteractions();
+
+        assertNoCachedTimeValueResult(ntpTrustedTime);
+    }
+
+    @Test
+    public void testForceRefresh_singleServer_querySucceeded() {
+        NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+        Network network = mock(Network.class);
+        when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
+        List<URI> serverUris = createUris("ntp://ntpserver.name");
+        when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
+                new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
+        NtpTrustedTime.TimeResult successResult = new NtpTrustedTime.TimeResult(123L, 456L, 789,
+                InetSocketAddress.createUnresolved("placeholder", 123));
+        when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
+                .thenReturn(successResult);
+
+        assertTrue(ntpTrustedTime.forceRefresh(network));
+
+        InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+        inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
+        inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+        inOrder.verify(ntpTrustedTime, times(1))
+                .queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
+        inOrder.verifyNoMoreInteractions();
+
+        assertCachedTimeValueResult(ntpTrustedTime, successResult);
+    }
+
+    @Test
+    public void testForceRefresh_multiServer_firstQueryFailed() {
+        NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+        Network network = mock(Network.class);
+        when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
+        List<URI> serverUris = createUris("ntp://ntpserver1.name", "ntp://ntpserver2.name");
+        when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
+                new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
+        when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
+                .thenReturn(null);
+        NtpTrustedTime.TimeResult successResult = new NtpTrustedTime.TimeResult(123L, 456L, 789,
+                InetSocketAddress.createUnresolved("placeholder", 123));
+        when(ntpTrustedTime.queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT))
+                .thenReturn(successResult);
+
+        assertTrue(ntpTrustedTime.forceRefresh(network));
+
+        InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+        inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
+        inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+        inOrder.verify(ntpTrustedTime, times(1))
+                .queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
+        inOrder.verify(ntpTrustedTime, times(1))
+                .queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT);
+        inOrder.verifyNoMoreInteractions();
+
+        assertCachedTimeValueResult(ntpTrustedTime, successResult);
+    }
+
+    @Test
+    public void testForceRefresh_multiServer_firstQuerySucceeded() {
+        NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+        Network network = mock(Network.class);
+        when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
+        List<URI> serverUris = createUris("ntp://ntpserver1.name", "ntp://ntpserver2.name");
+        when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
+                new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
+        NtpTrustedTime.TimeResult successResult = new NtpTrustedTime.TimeResult(123L, 456L, 789,
+                InetSocketAddress.createUnresolved("placeholder", 123));
+        when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
+                .thenReturn(successResult);
+
+        assertTrue(ntpTrustedTime.forceRefresh(network));
+
+        InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+        inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
+        inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+        inOrder.verify(ntpTrustedTime, times(1))
+                .queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
+        inOrder.verifyNoMoreInteractions();
+
+        assertCachedTimeValueResult(ntpTrustedTime, successResult);
+    }
+
+    @Test
+    public void testForceRefresh_multiServer_keepsOldValueOnFailure() {
+        NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+        Network network = mock(Network.class);
+        List<URI> serverUris = createUris("ntp://ntpserver1.name", "ntp://ntpserver2.name");
+        NtpTrustedTime.TimeResult successResult = new NtpTrustedTime.TimeResult(123L, 456L, 789,
+                InetSocketAddress.createUnresolved("placeholder", 123));
+
+        // First forceRefresh() succeeds.
+        {
+            when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
+            when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
+                    new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
+            when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
+                    .thenReturn(successResult);
+
+            assertTrue(ntpTrustedTime.forceRefresh(network));
+
+            InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+            inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
+            inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+            inOrder.verify(ntpTrustedTime, times(1))
+                    .queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
+            inOrder.verifyNoMoreInteractions();
+
+            assertCachedTimeValueResult(ntpTrustedTime, successResult);
+
+            reset(ntpTrustedTime);
+        }
+
+        // Next forceRefresh() fails, keeping the result of the first forceRefresh().
+        {
+            when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
+            when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
+                    new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
+            when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0),
+                    VALID_TIMEOUT)).thenReturn(null);
+            when(ntpTrustedTime.queryNtpServer(network, serverUris.get(1),
+                    VALID_TIMEOUT)).thenReturn(null);
+
+            assertFalse(ntpTrustedTime.forceRefresh(network));
+
+            InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+            inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
+            inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+            inOrder.verify(ntpTrustedTime, times(1))
+                    .queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
+            inOrder.verify(ntpTrustedTime, times(1))
+                    .queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT);
+            inOrder.verifyNoMoreInteractions();
+
+            assertCachedTimeValueResult(ntpTrustedTime, successResult);
+
+            reset(ntpTrustedTime);
+        }
+    }
+
+    /**
+     * A complex test demonstrating the properties of the multi-server algorithm in different
+     * scenarios / states.
+     */
+    @Test
+    public void testForceRefresh_multiServer_complex() {
+        NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+
+        Network network = mock(Network.class);
+        List<URI> serverUris = createUris(
+                "ntp://ntpserver1.name", "ntp://ntpserver2.name", "ntp://ntpserver3.name");
+        NtpTrustedTime.TimeResult successResult1 = new NtpTrustedTime.TimeResult(111L, 111L, 111,
+                InetSocketAddress.createUnresolved("placeholder", 111));
+        NtpTrustedTime.TimeResult successResult2 = new NtpTrustedTime.TimeResult(222L, 222L, 222,
+                InetSocketAddress.createUnresolved("placeholder", 222));
+        NtpTrustedTime.TimeResult successResult3 = new NtpTrustedTime.TimeResult(333L, 333L, 333,
+                InetSocketAddress.createUnresolved("placeholder", 333));
+
+        // The first forceRefresh() should the URIs in the original order. Here, we fail the first
+        // and succeed with the second.
+        {
+            when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
+            when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
+                    new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
+            when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
+                    .thenReturn(null);
+            when(ntpTrustedTime.queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT))
+                    .thenReturn(successResult1);
+
+            assertTrue(ntpTrustedTime.forceRefresh(network));
+
+            InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+            inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
+            inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+            inOrder.verify(ntpTrustedTime, times(1))
+                    .queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
+            inOrder.verify(ntpTrustedTime, times(1))
+                    .queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT);
+            inOrder.verifyNoMoreInteractions();
+
+            assertCachedTimeValueResult(ntpTrustedTime, successResult1);
+
+            reset(ntpTrustedTime);
+        }
+
+        // forceRefresh() should try starting with the last successful server, which will succeed.
+        {
+            when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
+            when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
+                    new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
+            when(ntpTrustedTime.queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT))
+                    .thenReturn(successResult2);
+
+            assertTrue(ntpTrustedTime.forceRefresh(network));
+
+            InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+            inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
+            inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+            inOrder.verify(ntpTrustedTime, times(1))
+                    .queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT);
+            inOrder.verifyNoMoreInteractions();
+
+            assertCachedTimeValueResult(ntpTrustedTime, successResult2);
+
+            reset(ntpTrustedTime);
+        }
+
+        // forceRefresh() should try starting with the last successful server, but try the others in
+        // order. It will succeed with the final server.
+        {
+            when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
+            when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
+                    new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
+            when(ntpTrustedTime.queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT))
+                    .thenReturn(null);
+            when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
+                    .thenReturn(null);
+            when(ntpTrustedTime.queryNtpServer(network, serverUris.get(2), VALID_TIMEOUT))
+                    .thenReturn(successResult3);
+
+            assertTrue(ntpTrustedTime.forceRefresh(network));
+
+            InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+            inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
+            inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+            inOrder.verify(ntpTrustedTime, times(1))
+                    .queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT);
+            inOrder.verify(ntpTrustedTime, times(1))
+                    .queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
+            inOrder.verify(ntpTrustedTime, times(1))
+                    .queryNtpServer(network, serverUris.get(2), VALID_TIMEOUT);
+            inOrder.verifyNoMoreInteractions();
+
+            assertCachedTimeValueResult(ntpTrustedTime, successResult3);
+
+            reset(ntpTrustedTime);
+        }
+
+        // forceRefresh() should try starting with the last successful server, but try the others in
+        // order. It will fail with all.
+        {
+            when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
+            when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
+                    new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
+            when(ntpTrustedTime.queryNtpServer(network, serverUris.get(2), VALID_TIMEOUT))
+                    .thenReturn(null);
+            when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
+                    .thenReturn(null);
+            when(ntpTrustedTime.queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT))
+                    .thenReturn(null);
+
+            assertFalse(ntpTrustedTime.forceRefresh(network));
+
+            InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+            inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
+            inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+            inOrder.verify(ntpTrustedTime, times(1))
+                    .queryNtpServer(network, serverUris.get(2), VALID_TIMEOUT);
+            inOrder.verify(ntpTrustedTime, times(1))
+                    .queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
+            inOrder.verify(ntpTrustedTime, times(1))
+                    .queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT);
+            inOrder.verifyNoMoreInteractions();
+
+            assertCachedTimeValueResult(ntpTrustedTime, successResult3);
+
+            reset(ntpTrustedTime);
+        }
+
+        // forceRefresh() should try starting with the last successful server, but try the others in
+        // order. It will succeed on the last.
+        {
+            when(ntpTrustedTime.isNetworkConnected(network)).thenReturn(true);
+            when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
+                    new NtpTrustedTime.NtpConfig(serverUris, VALID_TIMEOUT));
+            when(ntpTrustedTime.queryNtpServer(network, serverUris.get(2), VALID_TIMEOUT))
+                    .thenReturn(null);
+            when(ntpTrustedTime.queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT))
+                    .thenReturn(null);
+            when(ntpTrustedTime.queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT))
+                    .thenReturn(successResult1);
+
+            assertTrue(ntpTrustedTime.forceRefresh(network));
+
+            InOrder inOrder = Mockito.inOrder(ntpTrustedTime);
+            inOrder.verify(ntpTrustedTime, times(1)).isNetworkConnected(network);
+            inOrder.verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+            inOrder.verify(ntpTrustedTime, times(1))
+                    .queryNtpServer(network, serverUris.get(2), VALID_TIMEOUT);
+            inOrder.verify(ntpTrustedTime, times(1))
+                    .queryNtpServer(network, serverUris.get(0), VALID_TIMEOUT);
+            inOrder.verify(ntpTrustedTime, times(1))
+                    .queryNtpServer(network, serverUris.get(1), VALID_TIMEOUT);
+            inOrder.verifyNoMoreInteractions();
+
+            assertCachedTimeValueResult(ntpTrustedTime, successResult1);
+
+            reset(ntpTrustedTime);
+        }
+    }
+
+    private static Pair<String, String> identityPair(String both) {
+        return Pair.create(both, both);
+    }
+
+    private static List<URI> createUris(String... uriStrings) {
+        return Arrays.stream(uriStrings).map(URI::create).collect(Collectors.toList());
+    }
+
+    @SuppressWarnings("deprecation")
+    private static void assertNoCachedTimeValueResult(NtpTrustedTime ntpTrustedTime) {
+        assertFalse(ntpTrustedTime.hasCache());
+        assertEquals(0, ntpTrustedTime.getCachedNtpTime());
+        assertEquals(0, ntpTrustedTime.getCachedNtpTimeReference());
+        assertEquals(Long.MAX_VALUE, ntpTrustedTime.getCacheAge());
+        assertNull(ntpTrustedTime.getCachedTimeResult());
+    }
+
+    @SuppressWarnings("deprecation")
+    private static void assertCachedTimeValueResult(NtpTrustedTime ntpTrustedTime,
+            NtpTrustedTime.TimeResult expected) {
+        assertTrue(ntpTrustedTime.hasCache());
+        assertEquals(expected.getTimeMillis(), ntpTrustedTime.getCachedNtpTime());
+        assertEquals(expected.getElapsedRealtimeMillis(),
+                ntpTrustedTime.getCachedNtpTimeReference());
+        assertTrue(ntpTrustedTime.getCacheAge() != Long.MAX_VALUE);
+        assertEquals(expected, ntpTrustedTime.getCachedTimeResult());
+    }
+}
diff --git a/core/tests/coretests/src/android/util/OWNERS b/core/tests/coretests/src/android/util/OWNERS
new file mode 100644
index 0000000..460e8c0
--- /dev/null
+++ b/core/tests/coretests/src/android/util/OWNERS
@@ -0,0 +1,2 @@
+per-file NtpTrustedTimeTest.java = file:/services/core/java/com/android/server/timezonedetector/OWNERS
+per-file TypedValueTest.kt = file:/core/java/android/content/res/OWNERS
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/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/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/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/data/keyboards/Vendor_1038_Product_1434.kl b/data/keyboards/Vendor_1038_Product_1434.kl
new file mode 100644
index 0000000..8182edd
--- /dev/null
+++ b/data/keyboards/Vendor_1038_Product_1434.kl
@@ -0,0 +1,58 @@
+# 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.
+
+#
+# SteelSeries Stratus+
+# Autogenerated based on Vendor_045e_Product_02ea.kl (XBox One Controller - Model 1708)
+#
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+key 304   BUTTON_A
+key 305   BUTTON_B
+key 307   BUTTON_X
+key 308   BUTTON_Y
+
+key 310   BUTTON_L1
+key 311   BUTTON_R1
+
+# Triggers.
+axis 0x02 LTRIGGER
+axis 0x05 RTRIGGER
+
+# Left and right stick.
+# The reported value for flat is 128 out of a range from -32767 to 32768, which is absurd.
+# This confuses applications that rely on the flat value because the joystick actually
+# settles in a flat range of +/- 4096 or so.
+axis 0x00 X flat 4096
+axis 0x01 Y flat 4096
+axis 0x03 Z flat 4096
+axis 0x04 RZ flat 4096
+
+key 317   BUTTON_THUMBL
+key 318   BUTTON_THUMBR
+
+# Hat.
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Two overlapping rectangles
+key 314   BUTTON_SELECT
+# Hamburger - 3 parallel lines
+key 315   BUTTON_START
+
+# Xbox key
+key 316   BUTTON_MODE
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/identity/java/android/security/identity/Util.java b/identity/java/android/security/identity/Util.java
index e56bd51..789ff06 100644
--- a/identity/java/android/security/identity/Util.java
+++ b/identity/java/android/security/identity/Util.java
@@ -20,12 +20,12 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.math.BigInteger;
 import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
 import java.security.PublicKey;
 import java.security.interfaces.ECPublicKey;
 import java.security.spec.ECPoint;
-import java.util.Collection;
 
 import javax.crypto.Mac;
 import javax.crypto.spec.SecretKeySpec;
@@ -36,15 +36,6 @@
 public class Util {
     private static final String TAG = "Util";
 
-    static int[] integerCollectionToArray(Collection<Integer> collection) {
-        int[] result = new int[collection.size()];
-        int n = 0;
-        for (int item : collection) {
-            result[n++] = item;
-        }
-        return result;
-    }
-
     static byte[] stripLeadingZeroes(byte[] value) {
         int n = 0;
         while (n < value.length && value[n] == 0) {
@@ -61,15 +52,47 @@
 
     static byte[] publicKeyEncodeUncompressedForm(PublicKey publicKey) {
         ECPoint w = ((ECPublicKey) publicKey).getW();
-        // X and Y are always positive so for interop we remove any leading zeroes
-        // inserted by the BigInteger encoder.
-        byte[] x = stripLeadingZeroes(w.getAffineX().toByteArray());
-        byte[] y = stripLeadingZeroes(w.getAffineY().toByteArray());
+        BigInteger x = w.getAffineX();
+        BigInteger y = w.getAffineY();
+        if (x.compareTo(BigInteger.ZERO) < 0) {
+            throw new RuntimeException("X is negative");
+        }
+        if (y.compareTo(BigInteger.ZERO) < 0) {
+            throw new RuntimeException("Y is negative");
+        }
         try {
             ByteArrayOutputStream baos = new ByteArrayOutputStream();
             baos.write(0x04);
-            baos.write(x);
-            baos.write(y);
+
+            // Each coordinate may be encoded in 33*, 32, or fewer bytes.
+            //
+            //  * : it can be 33 bytes because toByteArray() guarantees "The array will contain the
+            //      minimum number of bytes required to represent this BigInteger, including at
+            //      least one sign bit, which is (ceil((this.bitLength() + 1)/8))" which means that
+            //      the MSB is always 0x00. This is taken care of by calling calling
+            //      stripLeadingZeroes().
+            //
+            // We need the encoding to be exactly 32 bytes since according to RFC 5480 section 2.2
+            // and SEC 1: Elliptic Curve Cryptography section 2.3.3 the encoding is 0x04 | X | Y
+            // where X and Y are encoded in exactly 32 byte, big endian integer values each.
+            //
+            byte[] xBytes = stripLeadingZeroes(x.toByteArray());
+            if (xBytes.length > 32) {
+                throw new RuntimeException("xBytes is " + xBytes.length + " which is unexpected");
+            }
+            for (int n = 0; n < 32 - xBytes.length; n++) {
+                baos.write(0x00);
+            }
+            baos.write(xBytes);
+
+            byte[] yBytes = stripLeadingZeroes(y.toByteArray());
+            if (yBytes.length > 32) {
+                throw new RuntimeException("yBytes is " + yBytes.length + " which is unexpected");
+            }
+            for (int n = 0; n < 32 - yBytes.length; n++) {
+                baos.write(0x00);
+            }
+            baos.write(yBytes);
             return baos.toByteArray();
         } catch (IOException e) {
             throw new RuntimeException("Unexpected IOException", e);
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
index 3ff5315..0dba6b0 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
@@ -72,6 +72,7 @@
                 @NonNull Configuration parentConfig);
         void onActivityReparentToTask(int taskId, @NonNull Intent activityIntent,
                 @NonNull IBinder activityToken);
+        void onTaskFragmentError(@Nullable TaskFragmentInfo taskFragmentInfo, int opType);
     }
 
     /**
@@ -323,4 +324,18 @@
             mCallback.onActivityReparentToTask(taskId, activityIntent, activityToken);
         }
     }
+
+    @Override
+    public void onTaskFragmentError(@NonNull IBinder errorCallbackToken,
+            @Nullable TaskFragmentInfo taskFragmentInfo,
+            int opType, @NonNull Throwable exception) {
+        if (taskFragmentInfo != null) {
+            final IBinder fragmentToken = taskFragmentInfo.getFragmentToken();
+            mFragmentInfos.put(fragmentToken, taskFragmentInfo);
+        }
+
+        if (mCallback != null) {
+            mCallback.onTaskFragmentError(taskFragmentInfo, opType);
+        }
+    }
 }
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..c688080 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -16,8 +16,11 @@
 
 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;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
 
 import static androidx.window.extensions.embedding.SplitContainer.getFinishPrimaryWithSecondaryBehavior;
 import static androidx.window.extensions.embedding.SplitContainer.getFinishSecondaryWithPrimaryBehavior;
@@ -97,6 +100,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 +112,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. */
@@ -293,6 +298,37 @@
         }
     }
 
+    @Override
+    public void onTaskFragmentError(@Nullable TaskFragmentInfo taskFragmentInfo, int opType) {
+        synchronized (mLock) {
+            switch (opType) {
+                case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT:
+                case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT: {
+                    final TaskFragmentContainer container;
+                    if (taskFragmentInfo != null) {
+                        container = getContainer(taskFragmentInfo.getFragmentToken());
+                    } else {
+                        container = null;
+                    }
+                    if (container == null) {
+                        break;
+                    }
+
+                    // Update the latest taskFragmentInfo and perform necessary clean-up
+                    container.setInfo(taskFragmentInfo);
+                    container.clearPendingAppearedActivities();
+                    if (container.isEmpty()) {
+                        mPresenter.cleanupContainer(container, false /* shouldFinishDependent */);
+                    }
+                    break;
+                }
+                default:
+                    Log.e(TAG, "onTaskFragmentError: taskFragmentInfo = " + taskFragmentInfo
+                            + ", opType = " + opType);
+            }
+        }
+    }
+
     /** Called on receiving {@link #onTaskFragmentVanished(TaskFragmentInfo)} for cleanup. */
     private void cleanupTaskFragment(@NonNull IBinder taskFragmentToken) {
         for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
@@ -1385,6 +1421,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 +1577,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 +1608,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..37f5b6d 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -193,11 +193,32 @@
         mPendingAppearedActivities.remove(pendingAppearedActivity);
     }
 
+    void clearPendingAppearedActivities() {
+        mPendingAppearedActivities.clear();
+        mPendingAppearedIntent = null;
+    }
+
     @Nullable
     Intent getPendingAppearedIntent() {
         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 +251,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/OWNERS b/libs/WindowManager/OWNERS
index 780e4c1..2c61df9 100644
--- a/libs/WindowManager/OWNERS
+++ b/libs/WindowManager/OWNERS
@@ -1,6 +1,3 @@
 set noparent
 
 include /services/core/java/com/android/server/wm/OWNERS
-
-# Give submodule owners in shell resource approval
-per-file Shell/res*/*/*.xml = hwwang@google.com, lbill@google.com, madym@google.com
diff --git a/libs/WindowManager/Shell/OWNERS b/libs/WindowManager/Shell/OWNERS
new file mode 100644
index 0000000..4b12590
--- /dev/null
+++ b/libs/WindowManager/Shell/OWNERS
@@ -0,0 +1,4 @@
+xutan@google.com
+
+# Give submodule owners in shell resource approval
+per-file res*/*/*.xml = hwwang@google.com, lbill@google.com, madym@google.com
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index e7bc74a..500ad5e5 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Instellings"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Gaan by verdeelde skerm in"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Kieslys"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in beeld-in-beeld"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"As jy nie wil hê dat <xliff:g id="NAME">%s</xliff:g> hierdie kenmerk moet gebruik nie, tik om instellings oop te maak en skakel dit af."</string>
     <string name="pip_play" msgid="3496151081459417097">"Speel"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Program sal dalk nie op \'n sekondêre skerm werk nie."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Program steun nie begin op sekondêre skerms nie."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Skermverdeler"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Volskerm links"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Links 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Links 50%"</string>
@@ -72,7 +76,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..2f4189d 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"ቅንብሮች"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"የተከፈለ ማያ ገጽን አስገባ"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"ምናሌ"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> በስዕል-ላይ-ስዕል ውስጥ ነው"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> ይህን ባህሪ እንዲጠቀም ካልፈለጉ ቅንብሮችን ለመክፈት መታ ያድርጉና ያጥፉት።"</string>
     <string name="pip_play" msgid="3496151081459417097">"አጫውት"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"መተግበሪያ በሁለተኛ ማሳያ ላይ ላይሠራ ይችላል።"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"መተግበሪያ በሁለተኛ ማሳያዎች ላይ ማስጀመርን አይደግፍም።"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"የተከፈለ የማያ ገጽ ከፋይ"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"የግራ ሙሉ ማያ ገጽ"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ግራ 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ግራ 50%"</string>
@@ -72,7 +76,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..1f5fc9d 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"الإعدادات"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"الدخول في وضع تقسيم الشاشة"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"القائمة"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> يظهر في صورة داخل صورة"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"إذا كنت لا تريد أن يستخدم <xliff:g id="NAME">%s</xliff:g> هذه الميزة، فانقر لفتح الإعدادات، ثم أوقِف تفعيل هذه الميزة."</string>
     <string name="pip_play" msgid="3496151081459417097">"تشغيل"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"قد لا يعمل التطبيق على شاشة عرض ثانوية."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"لا يمكن تشغيل التطبيق على شاشات عرض ثانوية."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"أداة تقسيم الشاشة"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"عرض النافذة اليسرى بملء الشاشة"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ضبط حجم النافذة اليسرى ليكون ٧٠%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ضبط حجم النافذة اليسرى ليكون ٥٠%"</string>
@@ -72,7 +76,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..ca3542e 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"ছেটিং"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"বিভাজিত স্ক্ৰীন ম’ডলৈ যাওক"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"মেনু"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> চিত্ৰৰ ভিতৰৰ চিত্ৰত আছে"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"আপুনি যদি <xliff:g id="NAME">%s</xliff:g> সুবিধাটো ব্যৱহাৰ কৰিব নোখোজে, তেন্তে ছেটিং খুলিবলৈ টিপক আৰু তালৈ গৈ ইয়াক অফ কৰক।"</string>
     <string name="pip_play" msgid="3496151081459417097">"প্লে কৰক"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"গৌণ ডিছপ্লেত এপে সঠিকভাৱে কাম নকৰিব পাৰে।"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"গৌণ ডিছপ্লেত এপ্ লঞ্চ কৰিব নোৱাৰি।"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"স্প্লিট স্ক্ৰীনৰ বিভাজক"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"বাওঁফালৰ স্ক্ৰীনখন সম্পূৰ্ণ স্ক্ৰীন কৰক"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"বাওঁফালৰ স্ক্ৰীণখন ৭০% কৰক"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"বাওঁফালৰ স্ক্ৰীণখন ৫০% কৰক"</string>
@@ -72,7 +76,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..25390bc 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -22,6 +22,7 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Ayarlar"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Bölünmüş ekrana daxil olun"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menyu"</string>
+    <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Şəkildə Şəkil Menyusu"</string>
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> şəkil içində şəkildədir"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> tətbiqinin bu funksiyadan istifadə etməyini istəmirsinizsə, ayarları açmaq və deaktiv etmək üçün klikləyin."</string>
     <string name="pip_play" msgid="3496151081459417097">"Oxudun"</string>
@@ -36,6 +37,7 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Tətbiq ikinci ekranda işləməyə bilər."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Tətbiq ikinci ekranda başlamağı dəstəkləmir."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Bölünmüş ekran ayırıcısı"</string>
+    <string name="divider_title" msgid="5482989479865361192">"Bölünmüş ekran ayırıcısı"</string>
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Sol tam ekran"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Sol 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Sol 50%"</string>
@@ -72,7 +74,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..f4cb20b 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Podešavanja"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Uđi na podeljeni ekran"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Meni"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je slika u slici"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Ako ne želite da <xliff:g id="NAME">%s</xliff:g> koristi ovu funkciju, dodirnite da biste otvorili podešavanja i isključili je."</string>
     <string name="pip_play" msgid="3496151081459417097">"Pusti"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće funkcionisati na sekundarnom ekranu."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Razdelnik podeljenog ekrana"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Režim celog ekrana za levi ekran"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Levi ekran 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Levi ekran 50%"</string>
@@ -72,7 +76,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..f1b4ca5 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Налады"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Падзяліць экран"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> з’яўляецца відарысам у відарысе"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Калі вы не хочаце, каб праграма <xliff:g id="NAME">%s</xliff:g> выкарыстоўвала гэту функцыю, дакраніцеся, каб адкрыць налады і адключыць яе."</string>
     <string name="pip_play" msgid="3496151081459417097">"Прайграць"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Праграма можа не працаваць на дадатковых экранах."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Праграма не падтрымлівае запуск на дадатковых экранах."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Раздзяляльнік падзеленага экрана"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Левы экран – поўнаэкранны рэжым"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Левы экран – 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Левы экран – 50%"</string>
@@ -72,7 +76,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..f7fbb3e 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Настройки"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Преминаване към разделен екран"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> е в режима „Картина в картината“"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Ако не искате <xliff:g id="NAME">%s</xliff:g> да използва тази функция, докоснете, за да отворите настройките, и я изключете."</string>
     <string name="pip_play" msgid="3496151081459417097">"Пускане"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Възможно е приложението да не работи на алтернативни дисплеи."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Приложението не поддържа използването на алтернативни дисплеи."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Разделител в режима за разделен екран"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ляв екран: Показване на цял екран"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Ляв екран: 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ляв екран: 50%"</string>
@@ -72,7 +76,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..0cb2f5e 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"সেটিংস"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"\'স্প্লিট স্ক্রিন\' মোড চালু করুন"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"মেনু"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"ছবির-মধ্যে-ছবি তে <xliff:g id="NAME">%s</xliff:g> আছেন"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> কে এই বৈশিষ্ট্যটি ব্যবহার করতে দিতে না চাইলে ট্যাপ করে সেটিংসে গিয়ে সেটি বন্ধ করে দিন।"</string>
     <string name="pip_play" msgid="3496151081459417097">"চালান"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"সেকেন্ডারি ডিসপ্লেতে অ্যাপটি কাজ নাও করতে পারে।"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"সেকেন্ডারি ডিসপ্লেতে অ্যাপ লঞ্চ করা যাবে না।"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"বিভক্ত-স্ক্রিন বিভাজক"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"বাঁ দিকের অংশ নিয়ে পূর্ণ স্ক্রিন"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"৭০% বাকি আছে"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"৫০% বাকি আছে"</string>
@@ -72,7 +76,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..c7086f1 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Postavke"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Otvori podijeljeni ekran"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Meni"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je u načinu priakza Slika u slici"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Ako ne želite da <xliff:g id="NAME">%s</xliff:g> koristi ovu funkciju, dodirnite da otvorite postavke i isključite je."</string>
     <string name="pip_play" msgid="3496151081459417097">"Reproduciraj"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće raditi na sekundarnom ekranu."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Razdjelnik ekrana"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Lijevo cijeli ekran"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Lijevo 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Lijevo 50%"</string>
@@ -72,7 +76,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..1bb1d08 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Configuració"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Entra al mode de pantalla dividida"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> està en pantalla en pantalla"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Si no vols que <xliff:g id="NAME">%s</xliff:g> utilitzi aquesta funció, toca per obrir la configuració i desactiva-la."</string>
     <string name="pip_play" msgid="3496151081459417097">"Reprodueix"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"És possible que l\'aplicació no funcioni en una pantalla secundària."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'aplicació no es pot obrir en pantalles secundàries."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Divisor de pantalles"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Pantalla esquerra completa"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Pantalla esquerra al 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Pantalla esquerra al 50%"</string>
@@ -72,7 +76,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..def3f4f 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Nastavení"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Aktivovat rozdělenou obrazovku"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Nabídka"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"Aplikace <xliff:g id="NAME">%s</xliff:g> je v režimu obraz v obraze"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Pokud nechcete, aby aplikace <xliff:g id="NAME">%s</xliff:g> tuto funkci používala, klepnutím otevřete nastavení a funkci vypněte."</string>
     <string name="pip_play" msgid="3496151081459417097">"Přehrát"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikace na sekundárním displeji nemusí fungovat."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikace nepodporuje spuštění na sekundárních displejích."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Čára rozdělující obrazovku"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Levá část na celou obrazovku"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70 % vlevo"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % vlevo"</string>
@@ -72,7 +76,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..6eedb83 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Indstillinger"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Åbn opdelt skærm"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> vises som integreret billede"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Hvis du ikke ønsker, at <xliff:g id="NAME">%s</xliff:g> skal benytte denne funktion, kan du åbne indstillingerne og deaktivere den."</string>
     <string name="pip_play" msgid="3496151081459417097">"Afspil"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen fungerer muligvis ikke på sekundære skærme."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan ikke åbnes på sekundære skærme."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Adskiller til opdelt skærm"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Vis venstre del i fuld skærm"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Venstre 70 %"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Venstre 50 %"</string>
@@ -72,7 +76,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..fce0bd4 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Einstellungen"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"„Geteilter Bildschirm“ aktivieren"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menü"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ist in Bild im Bild"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Wenn du nicht möchtest, dass <xliff:g id="NAME">%s</xliff:g> diese Funktion verwendet, tippe, um die Einstellungen zu öffnen und die Funktion zu deaktivieren."</string>
     <string name="pip_play" msgid="3496151081459417097">"Wiedergeben"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Die App funktioniert auf einem sekundären Display möglicherweise nicht."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Die App unterstützt den Start auf sekundären Displays nicht."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Bildschirmteiler"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Vollbild links"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70 % links"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % links"</string>
@@ -72,7 +76,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..cef4338 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -22,6 +22,7 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Ρυθμίσεις"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Μετάβαση σε διαχωρισμό οθόνης"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Μενού"</string>
+    <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Μενού λειτουργίας Picture-in-Picture"</string>
     <string name="pip_notification_title" msgid="1347104727641353453">"Η λειτουργία picture-in-picture είναι ενεργή σε <xliff:g id="NAME">%s</xliff:g>."</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Εάν δεν θέλετε να χρησιμοποιείται αυτή η λειτουργία από την εφαρμογή <xliff:g id="NAME">%s</xliff:g>, πατήστε για να ανοίξετε τις ρυθμίσεις και απενεργοποιήστε την."</string>
     <string name="pip_play" msgid="3496151081459417097">"Αναπαραγωγή"</string>
@@ -36,6 +37,7 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Η εφαρμογή ίσως να μην λειτουργήσει σε δευτερεύουσα οθόνη."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Η εφαρμογή δεν υποστηρίζει την εκκίνηση σε δευτερεύουσες οθόνες."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Διαχωριστικό οθόνης"</string>
+    <string name="divider_title" msgid="5482989479865361192">"Διαχωριστικό οθόνης"</string>
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Αριστερή πλήρης οθόνη"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Αριστερή 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Αριστερή 50%"</string>
@@ -72,7 +74,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..6a226ed 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -22,6 +22,7 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-picture menu"</string>
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"If you don\'t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string>
     <string name="pip_play" msgid="3496151081459417097">"Play"</string>
@@ -36,6 +37,7 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string>
+    <string name="divider_title" msgid="5482989479865361192">"Split screen divider"</string>
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Left full screen"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Left 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string>
@@ -72,7 +74,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..6a226ed 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -22,6 +22,7 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-picture menu"</string>
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"If you don\'t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string>
     <string name="pip_play" msgid="3496151081459417097">"Play"</string>
@@ -36,6 +37,7 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string>
+    <string name="divider_title" msgid="5482989479865361192">"Split screen divider"</string>
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Left full screen"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Left 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string>
@@ -72,7 +74,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..6a226ed 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -22,6 +22,7 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-picture menu"</string>
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"If you don\'t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string>
     <string name="pip_play" msgid="3496151081459417097">"Play"</string>
@@ -36,6 +37,7 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string>
+    <string name="divider_title" msgid="5482989479865361192">"Split screen divider"</string>
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Left full screen"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Left 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string>
@@ -72,7 +74,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..6a226ed 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -22,6 +22,7 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-picture menu"</string>
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"If you don\'t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string>
     <string name="pip_play" msgid="3496151081459417097">"Play"</string>
@@ -36,6 +37,7 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string>
+    <string name="divider_title" msgid="5482989479865361192">"Split screen divider"</string>
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Left full screen"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Left 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string>
@@ -72,7 +74,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..7a37389 100644
--- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
@@ -22,6 +22,7 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‎‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‎Settings‎‏‎‎‏‎"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‎‎‎‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‏‎Enter split screen‎‏‎‎‏‎"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‎‎Menu‎‏‎‎‏‎"</string>
+    <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‏‏‏‎‎‏‎‏‏‏‏‎‎‏‎Picture-in-Picture Menu‎‏‎‎‏‎"</string>
     <string name="pip_notification_title" msgid="1347104727641353453">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎ is in picture-in-picture‎‏‎‎‏‎"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‏‎‏‏‎‎‎‏‎‏‏‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎If you don\'t want ‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎ to use this feature, tap to open settings and turn it off.‎‏‎‎‏‎"</string>
     <string name="pip_play" msgid="3496151081459417097">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‏‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‎‎‎‏‎‎‏‎Play‎‏‎‎‏‎"</string>
@@ -36,6 +37,7 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‏‎‏‎‏‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‏‎‎‏‎‎‏‏‏‏‎App may not work on a secondary display.‎‏‎‎‏‎"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‏‎‏‏‎‎‏‎App does not support launch on secondary displays.‎‏‎‎‏‎"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎‏‏‏‎Split-screen divider‎‏‎‎‏‎"</string>
+    <string name="divider_title" msgid="5482989479865361192">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎Split-screen divider‎‏‎‎‏‎"</string>
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‏‎‎‎‎‏‏‎‎‏‏‎‎‎‎Left full screen‎‏‎‎‏‎"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‎‏‎‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‎‎Left 70%‎‏‎‎‏‎"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎Left 50%‎‏‎‎‏‎"</string>
@@ -72,7 +74,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..77626af 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Configuración"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Introducir pantalla dividida"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está en modo de Pantalla en pantalla"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Si no quieres que <xliff:g id="NAME">%s</xliff:g> use esta función, presiona para abrir la configuración y desactivarla."</string>
     <string name="pip_play" msgid="3496151081459417097">"Reproducir"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Es posible que la app no funcione en una pantalla secundaria."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"La app no puede iniciarse en pantallas secundarias."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Divisor de pantalla dividida"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Pantalla izquierda completa"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Izquierda: 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Izquierda: 50%"</string>
@@ -72,7 +76,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..f813324 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Ajustes"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Introducir pantalla dividida"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está en imagen en imagen"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Si no quieres que <xliff:g id="NAME">%s</xliff:g> utilice esta función, toca la notificación para abrir los ajustes y desactivarla."</string>
     <string name="pip_play" msgid="3496151081459417097">"Reproducir"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Es posible que la aplicación no funcione en una pantalla secundaria."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"La aplicación no se puede abrir en pantallas secundarias."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Dividir la pantalla"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Pantalla izquierda completa"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Izquierda 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Izquierda 50%"</string>
@@ -72,7 +76,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..9d9e5bc 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Seaded"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Ava jagatud ekraanikuva"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menüü"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> on režiimis Pilt pildis"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Kui te ei soovi, et rakendus <xliff:g id="NAME">%s</xliff:g> seda funktsiooni kasutaks, puudutage seadete avamiseks ja lülitage see välja."</string>
     <string name="pip_play" msgid="3496151081459417097">"Esita"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Rakendus ei pruugi teisesel ekraanil töötada."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Rakendus ei toeta teisestel ekraanidel käivitamist."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Ekraanijagaja"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Vasak täisekraan"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Vasak: 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vasak: 50%"</string>
@@ -72,7 +76,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..5894a0e 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Ezarpenak"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Sartu pantaila zatituan"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menua"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"Pantaila txiki gainjarrian dago <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> zerbitzuak eginbide hori erabiltzea nahi ez baduzu, sakatu hau ezarpenak ireki eta aukera desaktibatzeko."</string>
     <string name="pip_play" msgid="3496151081459417097">"Erreproduzitu"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Baliteke aplikazioak ez funtzionatzea bigarren mailako pantailetan."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikazioa ezin da abiarazi bigarren mailako pantailatan."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Pantaila-zatitzailea"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ezarri ezkerraldea pantaila osoan"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Ezarri ezkerraldea % 70en"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ezarri ezkerraldea % 50en"</string>
@@ -72,7 +76,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..bc003cc 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"تنظیمات"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"ورود به حالت «صفحهٔ دونیمه»"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"منو"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> درحالت تصویر در تصویر است"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"اگر نمی‌خواهید <xliff:g id="NAME">%s</xliff:g> از این قابلیت استفاده کند، با ضربه زدن، تنظیمات را باز کنید و آن را خاموش کنید."</string>
     <string name="pip_play" msgid="3496151081459417097">"پخش"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ممکن است برنامه در نمایشگر ثانویه کار نکند."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"برنامه از راه‌اندازی در نمایشگرهای ثانویه پشتیبانی نمی‌کند."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"تقسیم‌کننده صفحه"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"تمام‌صفحه چپ"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"٪۷۰ چپ"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"٪۵۰ چپ"</string>
@@ -72,7 +76,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..2735be2 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Asetukset"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Avaa jaettu näyttö"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Valikko"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> on kuva kuvassa ‑tilassa"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Jos et halua, että <xliff:g id="NAME">%s</xliff:g> voi käyttää tätä ominaisuutta, avaa asetukset napauttamalla ja poista se käytöstä."</string>
     <string name="pip_play" msgid="3496151081459417097">"Toista"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Sovellus ei ehkä toimi toissijaisella näytöllä."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Sovellus ei tue käynnistämistä toissijaisilla näytöillä."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Näytön jakaja"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Vasen koko näytölle"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Vasen 70 %"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vasen 50 %"</string>
@@ -72,7 +76,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..f016134 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Paramètres"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Entrer dans l\'écran partagé"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> est en mode d\'incrustation d\'image"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Si vous ne voulez pas que <xliff:g id="NAME">%s</xliff:g> utilise cette fonctionnalité, touchez l\'écran pour ouvrir les paramètres, puis désactivez-la."</string>
     <string name="pip_play" msgid="3496151081459417097">"Lire"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'application ne peut pas être lancée sur des écrans secondaires."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Séparateur d\'écran partagé"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Plein écran à la gauche"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70 % à la gauche"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % à la gauche"</string>
@@ -72,7 +76,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..f1f8abe 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Paramètres"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Accéder à l\'écran partagé"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> est en mode Picture-in-picture"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Si vous ne voulez pas que l\'application <xliff:g id="NAME">%s</xliff:g> utilise cette fonctionnalité, appuyez ici pour ouvrir les paramètres et la désactiver."</string>
     <string name="pip_play" msgid="3496151081459417097">"Lecture"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'application ne peut pas être lancée sur des écrans secondaires."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Séparateur d\'écran partagé"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Écran de gauche en plein écran"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Écran de gauche à 70 %"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Écran de gauche à 50 %"</string>
@@ -72,7 +76,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..6067424 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Configuración"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Inserir pantalla dividida"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está na pantalla superposta"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Se non queres que <xliff:g id="NAME">%s</xliff:g> utilice esta función, toca a configuración para abrir as opcións e desactivar a función."</string>
     <string name="pip_play" msgid="3496151081459417097">"Reproducir"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É posible que a aplicación non funcione nunha pantalla secundaria."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"A aplicación non se pode iniciar en pantallas secundarias."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Divisor de pantalla dividida"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Pantalla completa á esquerda"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70 % á esquerda"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % á esquerda"</string>
@@ -72,7 +76,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..4e4d41c 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"સેટિંગ"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"વિભાજિત સ્ક્રીન મોડમાં દાખલ થાઓ"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"મેનૂ"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ચિત્રમાં-ચિત્રની અંદર છે"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"જો તમે નથી ઇચ્છતા કે <xliff:g id="NAME">%s</xliff:g> આ સુવિધાનો ઉપયોગ કરે, તો સેટિંગ ખોલવા માટે ટૅપ કરો અને તેને બંધ કરો."</string>
     <string name="pip_play" msgid="3496151081459417097">"ચલાવો"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ઍપ્લિકેશન ગૌણ ડિસ્પ્લે પર કદાચ કામ ન કરે."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ઍપ્લિકેશન ગૌણ ડિસ્પ્લે પર લૉન્ચનું સમર્થન કરતી નથી."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"સ્પ્લિટ-સ્ક્રીન વિભાજક"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ડાબી પૂર્ણ સ્ક્રીન"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ડાબે 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ડાબે 50%"</string>
@@ -72,7 +76,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..dad0db8 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"सेटिंग"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"स्प्लिट स्क्रीन मोड में जाएं"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"मेन्यू"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> \"पिक्चर में पिक्चर\" के अंदर है"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"अगर आप नहीं चाहते कि <xliff:g id="NAME">%s</xliff:g> इस सुविधा का उपयोग करे, तो सेटिंग खोलने के लिए टैप करें और उसे बंद करें ."</string>
     <string name="pip_play" msgid="3496151081459417097">"चलाएं"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"हो सकता है कि ऐप प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर काम न करे."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर ऐप लॉन्च नहीं किया जा सकता."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"विभाजित स्क्रीन विभाजक"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"बाईं स्क्रीन को फ़ुल स्क्रीन बनाएं"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"बाईं स्क्रीन को 70% बनाएं"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"बाईं स्क्रीन को 50% बनाएं"</string>
@@ -72,7 +76,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..ad25eb9 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Postavke"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Otvorite podijeljeni zaslon"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Izbornik"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> jest na slici u slici"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Ako ne želite da aplikacija <xliff:g id="NAME">%s</xliff:g> upotrebljava tu značajku, dodirnite da biste otvorili postavke i isključili je."</string>
     <string name="pip_play" msgid="3496151081459417097">"Reproduciraj"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće funkcionirati na sekundarnom zaslonu."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim zaslonima."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Razdjelnik podijeljenog zaslona"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Lijevi zaslon u cijeli zaslon"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Lijevi zaslon na 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Lijevi zaslon na 50%"</string>
@@ -72,7 +76,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..9b657b1 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Beállítások"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Váltás osztott képernyőre"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menü"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"A(z) <xliff:g id="NAME">%s</xliff:g> kép a képben funkciót használ"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Ha nem szeretné, hogy a(z) <xliff:g id="NAME">%s</xliff:g> használja ezt a funkciót, koppintson a beállítások megnyitásához, és kapcsolja ki."</string>
     <string name="pip_play" msgid="3496151081459417097">"Lejátszás"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Előfordulhat, hogy az alkalmazás nem működik másodlagos kijelzőn."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Az alkalmazást nem lehet másodlagos kijelzőn elindítani."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Elválasztó az osztott nézetben"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Bal oldali teljes képernyőre"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Bal oldali 70%-ra"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Bal oldali 50%-ra"</string>
@@ -72,7 +76,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..41bcb8f 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Կարգավորումներ"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Մտնել տրոհված էկրանի ռեժիմ"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Ընտրացանկ"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>-ը «Նկար նկարի մեջ» ռեժիմում է"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Եթե չեք ցանկանում, որ <xliff:g id="NAME">%s</xliff:g>-ն օգտագործի այս գործառույթը, հպեք՝ կարգավորումները բացելու և այն անջատելու համար։"</string>
     <string name="pip_play" msgid="3496151081459417097">"Նվագարկել"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Հավելվածը կարող է չաշխատել լրացուցիչ էկրանի վրա"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Հավելվածը չի աջակցում գործարկումը լրացուցիչ էկրանների վրա"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Տրոհված էկրանի բաժանիչ"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ձախ էկրանը՝ լիաէկրան"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Ձախ էկրանը՝ 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ձախ էկրանը՝ 50%"</string>
@@ -72,7 +76,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..0245b45 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Setelan"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Masuk ke mode layar terpisah"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> adalah picture-in-picture"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Jika Anda tidak ingin <xliff:g id="NAME">%s</xliff:g> menggunakan fitur ini, ketuk untuk membuka setelan dan menonaktifkannya."</string>
     <string name="pip_play" msgid="3496151081459417097">"Putar"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikasi mungkin tidak berfungsi pada layar sekunder."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikasi tidak mendukung peluncuran pada layar sekunder."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Pembagi layar terpisah"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Layar penuh di kiri"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Kiri 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kiri 50%"</string>
@@ -72,7 +76,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..bcae730 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Stillingar"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Opna skjáskiptingu"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Valmynd"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> er með mynd í mynd"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Ef þú vilt ekki að <xliff:g id="NAME">%s</xliff:g> noti þennan eiginleika skaltu ýta til að opna stillingarnar og slökkva á því."</string>
     <string name="pip_play" msgid="3496151081459417097">"Spila"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Hugsanlegt er að forritið virki ekki á öðrum skjá."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Forrit styður ekki opnun á öðrum skjá."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Skjáskipting"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Vinstri á öllum skjánum"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Vinstri 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vinstri 50%"</string>
@@ -72,7 +76,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..0f586a7 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Impostazioni"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Accedi a schermo diviso"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> è in Picture in picture"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Se non desideri che l\'app <xliff:g id="NAME">%s</xliff:g> utilizzi questa funzione, tocca per aprire le impostazioni e disattivarla."</string>
     <string name="pip_play" msgid="3496151081459417097">"Riproduci"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"L\'app potrebbe non funzionare su un display secondario."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'app non supporta l\'avvio su display secondari."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Strumento per schermo diviso"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Schermata sinistra a schermo intero"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Schermata sinistra al 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Schermata sinistra al 50%"</string>
@@ -72,7 +76,7 @@
     <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>
+    <string name="restart_button_description" msgid="6712141648865547958">"Tocca per riavviare quest\'app per una migliore visualizzazione."</string>
     <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..16aa4df 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"הגדרות"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"כניסה למסך המפוצל"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"תפריט"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> במצב תמונה בתוך תמונה"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"אם אינך רוצה שהתכונה הזו תשמש את <xliff:g id="NAME">%s</xliff:g>, יש להקיש כדי לפתוח את ההגדרות ולהשבית את התכונה."</string>
     <string name="pip_play" msgid="3496151081459417097">"הפעלה"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ייתכן שהאפליקציה לא תפעל במסך משני."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"האפליקציה אינה תומכת בהפעלה במסכים משניים."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"מחלק מסך מפוצל"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"מסך שמאלי מלא"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"שמאלה 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"שמאלה 50%"</string>
@@ -72,7 +76,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..67f58b8 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"設定"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"分割画面に切り替え"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"メニュー"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>はピクチャー イン ピクチャーで表示中です"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g>でこの機能を使用しない場合は、タップして設定を開いて OFF にしてください。"</string>
     <string name="pip_play" msgid="3496151081459417097">"再生"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"アプリはセカンダリ ディスプレイでは動作しないことがあります。"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"アプリはセカンダリ ディスプレイでの起動に対応していません。"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"分割画面の分割線"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"左全画面"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"左 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"左 50%"</string>
@@ -72,7 +76,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..9220a36 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"პარამეტრები"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"გაყოფილ ეკრანში შესვლა"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"მენიუ"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> იყენებს რეჟიმს „ეკრანი ეკრანში“"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"თუ არ გსურთ, რომ <xliff:g id="NAME">%s</xliff:g> ამ ფუნქციას იყენებდეს, აქ შეხებით შეგიძლიათ გახსნათ პარამეტრები და გამორთოთ ის."</string>
     <string name="pip_play" msgid="3496151081459417097">"დაკვრა"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"აპმა შეიძლება არ იმუშაოს მეორეულ ეკრანზე."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"აპს არ გააჩნია მეორეული ეკრანის მხარდაჭერა."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"გაყოფილი ეკრანის რეჟიმის გამყოფი"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"მარცხენა ნაწილის სრულ ეკრანზე გაშლა"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"მარცხენა ეკრანი — 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"მარცხენა ეკრანი — 50%"</string>
@@ -72,7 +76,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..9ccd5f2 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Параметрлер"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Бөлінген экранға кіру"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Mәзір"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> \"суреттегі сурет\" режимінде"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> деген пайдаланушының бұл мүмкіндікті пайдалануын қаламасаңыз, параметрлерді түртіп ашыңыз да, оларды өшіріңіз."</string>
     <string name="pip_play" msgid="3496151081459417097">"Ойнату"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Қолданба қосымша дисплейде жұмыс істемеуі мүмкін."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Қолданба қосымша дисплейлерде іске қосуды қолдамайды."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Бөлінген экран бөлгіші"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Сол жағын толық экранға шығару"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70% сол жақта"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% сол жақта"</string>
@@ -72,7 +76,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..fbf7add 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"ការកំណត់"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"ចូលមុខងារ​បំបែកអេក្រង់"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"ម៉ឺនុយ"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ស្ថិតក្នុងមុខងាររូបក្នុងរូប"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"ប្រសិនបើ​អ្នក​មិន​ចង់​ឲ្យ <xliff:g id="NAME">%s</xliff:g> ប្រើ​មុខងារ​នេះ​ សូមចុច​​បើក​ការកំណត់ រួច​បិទ​វា។"</string>
     <string name="pip_play" msgid="3496151081459417097">"លេង"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"កម្មវិធីនេះ​ប្រហែល​ជាមិនដំណើរការ​នៅលើ​អេក្រង់បន្ទាប់បន្សំទេ។"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"កម្មវិធី​នេះមិន​អាច​ចាប់ផ្តើម​នៅលើ​អេក្រង់បន្ទាប់បន្សំបានទេ។"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"កម្មវិធីចែកអេក្រង់បំបែក"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"អេក្រង់ពេញខាងឆ្វេង"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ឆ្វេង 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ឆ្វេង 50%"</string>
@@ -72,7 +76,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..62a2d52 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"ಸ್ಪ್ಲಿಟ್‌-ಸ್ಕ್ರೀನ್‌ಗೆ ಪ್ರವೇಶಿಸಿ"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"ಮೆನು"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರವಾಗಿದೆ"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> ಈ ವೈಶಿಷ್ಟ್ಯ ಬಳಸುವುದನ್ನು ನೀವು ಬಯಸದಿದ್ದರೆ, ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಲು ಮತ್ತು ಅದನ್ನು ಆಫ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="pip_play" msgid="3496151081459417097">"ಪ್ಲೇ"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ಸೆಕೆಂಡರಿ ಡಿಸ್‌ಪ್ಲೇಗಳಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್‌ ಕಾರ್ಯ ನಿರ್ವಹಿಸದೇ ಇರಬಹುದು."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ಸೆಕೆಂಡರಿ ಡಿಸ್‌ಪ್ಲೇಗಳಲ್ಲಿ ಪ್ರಾರಂಭಿಸುವಿಕೆಯನ್ನು ಅಪ್ಲಿಕೇಶನ್ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"ಸ್ಪ್ಲಿಟ್-ಪರದೆ ಡಿವೈಡರ್"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ಎಡ ಪೂರ್ಣ ಪರದೆ"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70% ಎಡಕ್ಕೆ"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% ಎಡಕ್ಕೆ"</string>
@@ -72,7 +76,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..82c80b8 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"설정"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"화면 분할 모드로 전환"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"메뉴"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>에서 PIP 사용 중"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g>에서 이 기능이 사용되는 것을 원하지 않는 경우 탭하여 설정을 열고 기능을 사용 중지하세요."</string>
     <string name="pip_play" msgid="3496151081459417097">"재생"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"앱이 보조 디스플레이에서 작동하지 않을 수도 있습니다."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"앱이 보조 디스플레이에서의 실행을 지원하지 않습니다."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"화면 분할기"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"왼쪽 화면 전체화면"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"왼쪽 화면 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"왼쪽 화면 50%"</string>
@@ -72,7 +76,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..0b1f83f 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Жөндөөлөр"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Экранды бөлүү режимине өтүү"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> – сүрөт ичиндеги сүрөт"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Эгер <xliff:g id="NAME">%s</xliff:g> колдонмосу бул функцияны пайдаланбасын десеңиз, жөндөөлөрдү ачып туруп, аны өчүрүп коюңуз."</string>
     <string name="pip_play" msgid="3496151081459417097">"Ойнотуу"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Колдонмо кошумча экранда иштебей коюшу мүмкүн."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Колдонмону кошумча экрандарда иштетүүгө болбойт."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Экранды бөлгүч"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Сол жактагы экранды толук экран режимине өткөрүү"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Сол жактагы экранды 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Сол жактагы экранды 50%"</string>
@@ -72,7 +76,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..ec468a5 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"ການຕັ້ງຄ່າ"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"ເຂົ້າການແບ່ງໜ້າຈໍ"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"ເມນູ"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ແມ່ນເປັນການສະແດງຜົນຫຼາຍຢ່າງພ້ອມກັນ"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"ຫາກທ່ານບໍ່ຕ້ອງການ <xliff:g id="NAME">%s</xliff:g> ໃຫ້ໃຊ້ຄຸນສົມບັດນີ້, ໃຫ້ແຕະເພື່ອເປີດການຕັ້ງຄ່າ ແລ້ວປິດມັນໄວ້."</string>
     <string name="pip_play" msgid="3496151081459417097">"ຫຼິ້ນ"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ແອັບອາດບໍ່ສາມາດໃຊ້ໄດ້ໃນໜ້າຈໍທີສອງ."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ແອັບບໍ່ຮອງຮັບການເປີດໃນໜ້າຈໍທີສອງ."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"ຕົວຂັ້ນການແບ່ງໜ້າຈໍ"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ເຕັມໜ້າຈໍຊ້າຍ"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ຊ້າຍ 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ຊ້າຍ 50%"</string>
@@ -72,7 +76,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..fdb51fc 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Nustatymai"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Įjungti išskaidyto ekrano režimą"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Meniu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> rodom. vaizdo vaizde"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Jei nenorite, kad „<xliff:g id="NAME">%s</xliff:g>“ naudotų šią funkciją, palietę atidarykite nustatymus ir išjunkite ją."</string>
     <string name="pip_play" msgid="3496151081459417097">"Leisti"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Programa gali neveikti antriniame ekrane."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Programa nepalaiko paleisties antriniuose ekranuose."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Skaidyto ekrano daliklis"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Kairysis ekranas viso ekrano režimu"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Kairysis ekranas 70 %"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kairysis ekranas 50 %"</string>
@@ -72,7 +76,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..ca666ce 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Iestatījumi"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Piekļūt ekrāna sadalīšanas režīmam"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Izvēlne"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ir attēlā attēlā"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Ja nevēlaties lietotnē <xliff:g id="NAME">%s</xliff:g> izmantot šo funkciju, pieskarieties, lai atvērtu iestatījumus un izslēgtu funkciju."</string>
     <string name="pip_play" msgid="3496151081459417097">"Atskaņot"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Lietotne, iespējams, nedarbosies sekundārajā displejā."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Lietotnē netiek atbalstīta palaišana sekundārajos displejos."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Ekrāna sadalītājs"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Kreisā daļa pa visu ekrānu"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Pa kreisi 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Pa kreisi 50%"</string>
@@ -72,7 +76,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..64b1cbc 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Поставки"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Влези во поделен екран"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Мени"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> е во слика во слика"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Ако не сакате <xliff:g id="NAME">%s</xliff:g> да ја користи функцијава, допрете за да ги отворите поставките и да ја исклучите."</string>
     <string name="pip_play" msgid="3496151081459417097">"Пушти"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апликацијата може да не функционира на друг екран."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Апликацијата не поддржува стартување на други екрани."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Разделник на поделен екран"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Левиот на цел екран"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Левиот 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Левиот 50%"</string>
@@ -72,7 +76,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..6b6af06 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"ക്രമീകരണം"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"സ്ക്രീൻ വിഭജന മോഡിൽ പ്രവേശിക്കുക"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"മെനു"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ചിത്രത്തിനുള്ളിൽ ചിത്രം രീതിയിലാണ്"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> ഈ ഫീച്ചർ ഉപയോഗിക്കേണ്ടെങ്കിൽ, ടാപ്പ് ചെയ്‌ത് ക്രമീകരണം തുറന്ന് അത് ഓഫാക്കുക."</string>
     <string name="pip_play" msgid="3496151081459417097">"പ്ലേ ചെയ്യുക"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"രണ്ടാം ഡിസ്‌പ്ലേയിൽ ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"രണ്ടാം ഡിസ്‌പ്ലേകളിൽ സമാരംഭിക്കുന്നതിനെ ആപ്പ് അനുവദിക്കുന്നില്ല."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"സ്പ്ലിറ്റ്-സ്ക്രീൻ ഡിവൈഡർ"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ഇടത് പൂർണ്ണ സ്ക്രീൻ"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ഇടത് 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ഇടത് 50%"</string>
@@ -72,7 +76,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..2cb48c2 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Тохиргоо"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Хуваасан дэлгэцийг оруулна уу"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Цэс"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> дэлгэцэн доторх дэлгэцэд байна"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Та <xliff:g id="NAME">%s</xliff:g>-д энэ онцлогийг ашиглуулахыг хүсэхгүй байвал тохиргоог нээгээд, үүнийг унтраана уу."</string>
     <string name="pip_play" msgid="3496151081459417097">"Тоглуулах"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апп хоёрдогч дэлгэцэд ажиллахгүй."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Аппыг хоёрдогч дэлгэцэд эхлүүлэх боломжгүй."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"\"Дэлгэц хуваах\" хуваагч"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Зүүн талын бүтэн дэлгэц"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Зүүн 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Зүүн 50%"</string>
@@ -72,7 +76,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..73c709f 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"सेटिंग्ज"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"स्प्लिट स्क्रीन एंटर करा"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"मेनू"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> चित्रामध्ये चित्र मध्ये आहे"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g>ने हे वैशिष्ट्य वापरू नये असे तुम्हाला वाटत असल्यास, सेटिंग्ज उघडण्यासाठी टॅप करा आणि ते बंद करा."</string>
     <string name="pip_play" msgid="3496151081459417097">"प्ले करा"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"दुसऱ्या डिस्प्लेवर अ‍ॅप कदाचित चालणार नाही."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"दुसऱ्या डिस्प्लेवर अ‍ॅप लाँच होणार नाही."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"विभाजित-स्क्रीन विभाजक"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"डावी फुल स्क्रीन"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"डावी 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"डावी 50%"</string>
@@ -72,7 +76,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..4368684 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Tetapan"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Masuk skrin pisah"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> terdapat dalam gambar dalam gambar"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Jika anda tidak mahu <xliff:g id="NAME">%s</xliff:g> menggunakan ciri ini, ketik untuk membuka tetapan dan matikan ciri."</string>
     <string name="pip_play" msgid="3496151081459417097">"Main"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Apl mungkin tidak berfungsi pada paparan kedua."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Apl tidak menyokong pelancaran pada paparan kedua."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Pembahagi skrin pisah"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Skrin penuh kiri"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Kiri 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kiri 50%"</string>
@@ -72,7 +76,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..be61336 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"ဆက်တင်များ"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းသို့ ဝင်ရန်"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"မီနူး"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> သည် နှစ်ခုထပ်၍ကြည့်ခြင်း ဖွင့်ထားသည်"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> အား ဤဝန်ဆောင်မှုကို အသုံးမပြုစေလိုလျှင် ဆက်တင်ကိုဖွင့်ရန် တို့ပြီး ၎င်းဝန်ဆောင်မှုကို ပိတ်လိုက်ပါ။"</string>
     <string name="pip_play" msgid="3496151081459417097">"ဖွင့်ရန်"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ဤအက်ပ်အနေဖြင့် ဒုတိယဖန်သားပြင်ပေါ်တွင် အလုပ်လုပ်မည် မဟုတ်ပါ။"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ဤအက်ပ်အနေဖြင့် ဖွင့်ရန်စနစ်ကို ဒုတိယဖန်သားပြင်မှ အသုံးပြုရန် ပံ့ပိုးမထားပါ။"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"မျက်နှာပြင်ခွဲခြမ်း ပိုင်းခြားပေးသည့်စနစ်"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ဘယ်ဘက် မျက်နှာပြင်အပြည့်"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ဘယ်ဘက်မျက်နှာပြင် ၇၀%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ဘယ်ဘက် မျက်နှာပြင် ၅၀%"</string>
@@ -72,7 +76,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..ae771e5 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Innstillinger"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Aktivér delt skjerm"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Meny"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> er i bilde-i-bilde"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Hvis du ikke vil at <xliff:g id="NAME">%s</xliff:g> skal bruke denne funksjonen, kan du trykke for å åpne innstillingene og slå den av."</string>
     <string name="pip_play" msgid="3496151081459417097">"Spill av"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen fungerer kanskje ikke på en sekundær skjerm."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan ikke kjøres på sekundære skjermer."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Skilleelement for delt skjerm"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Utvid den venstre delen av skjermen til hele skjermen"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Sett størrelsen på den venstre delen av skjermen til 70 %"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Sett størrelsen på den venstre delen av skjermen til 50 %"</string>
@@ -72,7 +76,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..692e985 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"सेटिङहरू"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"स्प्लिट स्क्रिन मोड प्रयोग गर्नुहोस्"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"मेनु"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> Picture-in-picture मा छ"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"तपाईं <xliff:g id="NAME">%s</xliff:g> ले सुविधा प्रयोग नगरोस् भन्ने चाहनुहुन्छ भने ट्याप गरेर सेटिङहरू खोल्नुहोस् र यसलाई निष्क्रिय पार्नुहोस्।"</string>
     <string name="pip_play" msgid="3496151081459417097">"प्ले गर्नुहोस्"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"यो एपले सहायक प्रदर्शनमा काम नगर्नसक्छ।"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"अनुप्रयोगले सहायक प्रदर्शनहरूमा लञ्च सुविधालाई समर्थन गर्दैन।"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"विभाजित-स्क्रिन छुट्याउने"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"बायाँ भाग फुल स्क्रिन"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"बायाँ भाग ७०%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"बायाँ भाग ५०%"</string>
@@ -72,7 +76,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..55c62ae 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Instellingen"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Gesplitst scherm openen"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in scherm-in-scherm"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Als je niet wilt dat <xliff:g id="NAME">%s</xliff:g> deze functie gebruikt, tik je om de instellingen te openen en zet je de functie uit."</string>
     <string name="pip_play" msgid="3496151081459417097">"Afspelen"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App werkt mogelijk niet op een secundair scherm."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App kan niet op secundaire displays worden gestart."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Scheiding voor gesplitst scherm"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Linkerscherm op volledig scherm"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Linkerscherm 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Linkerscherm 50%"</string>
@@ -72,7 +76,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..1cfda26 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"ସେଟିଂସ୍"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ମୋଡ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"ମେନୁ"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> \"ଛବି-ଭିତରେ-ଛବି\"ରେ ଅଛି"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"ଏହି ବୈଶିଷ୍ଟ୍ୟ <xliff:g id="NAME">%s</xliff:g> ବ୍ୟବହାର ନକରିବାକୁ ଯଦି ଆପଣ ଚାହାଁନ୍ତି, ସେଟିଙ୍ଗ ଖୋଲିବାକୁ ଟାପ୍‍ କରନ୍ତୁ ଏବଂ ଏହା ଅଫ୍‍ କରିଦିଅନ୍ତୁ।"</string>
     <string name="pip_play" msgid="3496151081459417097">"ପ୍ଲେ କରନ୍ତୁ"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍‍ କାମ ନକରିପାରେ।"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍‍ ଲଞ୍ଚ ସପୋର୍ଟ କରେ ନାହିଁ।"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"ସ୍ପ୍ଲିଟ୍‍-ସ୍କ୍ରୀନ ବିଭାଜକ"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ବାମ ପଟକୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍‍ କରନ୍ତୁ"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ବାମ ପଟକୁ 70% କରନ୍ତୁ"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ବାମ ପଟକୁ 50% କରନ୍ତୁ"</string>
@@ -72,7 +76,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..5c0c601 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"ਸੈਟਿੰਗਾਂ"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"ਮੀਨੂ"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ਤਸਵੀਰ-ਅੰਦਰ-ਤਸਵੀਰ ਵਿੱਚ ਹੈ"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"ਜੇਕਰ ਤੁਸੀਂ ਨਹੀਂ ਚਾਹੁੰਦੇ ਕਿ <xliff:g id="NAME">%s</xliff:g> ਐਪ ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਦੀ ਵਰਤੋਂ ਕਰੇ, ਤਾਂ ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹਣ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਇਸਨੂੰ ਬੰਦ ਕਰੋ।"</string>
     <string name="pip_play" msgid="3496151081459417097">"ਚਲਾਓ"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇ \'ਤੇ ਕੰਮ ਨਾ ਕਰੇ।"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇਆਂ \'ਤੇ ਲਾਂਚ ਕਰਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਡਿਵਾਈਡਰ"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ਖੱਬੇ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ਖੱਬੇ 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ਖੱਬੇ 50%"</string>
@@ -72,7 +76,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..1879649a 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Ustawienia"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Włącz podzielony ekran"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"Aplikacja <xliff:g id="NAME">%s</xliff:g> działa w trybie obraz w obrazie"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Jeśli nie chcesz, by aplikacja <xliff:g id="NAME">%s</xliff:g> korzystała z tej funkcji, otwórz ustawienia i wyłącz ją."</string>
     <string name="pip_play" msgid="3496151081459417097">"Odtwórz"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacja może nie działać na dodatkowym ekranie."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacja nie obsługuje uruchamiania na dodatkowych ekranach."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Linia dzielenia ekranu"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Lewa część ekranu na pełnym ekranie"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70% lewej części ekranu"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% lewej części ekranu"</string>
@@ -72,7 +76,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..d3fb14d 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Configurações"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Dividir tela"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está em picture-in-picture"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Se você não quer que o app <xliff:g id="NAME">%s</xliff:g> use este recurso, toque para abrir as configurações e desativá-lo."</string>
     <string name="pip_play" msgid="3496151081459417097">"Reproduzir"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É possível que o app não funcione em uma tela secundária."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"O app não é compatível com a inicialização em telas secundárias."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Divisor de tela"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Lado esquerdo em tela cheia"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Esquerda a 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Esquerda a 50%"</string>
@@ -72,7 +76,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..1d78dcb 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Definições"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Aceder ao ecrã dividido"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"A app <xliff:g id="NAME">%s</xliff:g> está no modo de ecrã no ecrã"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Se não pretende que a app <xliff:g id="NAME">%s</xliff:g> utilize esta funcionalidade, toque para abrir as definições e desative-a."</string>
     <string name="pip_play" msgid="3496151081459417097">"Reproduzir"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"A app pode não funcionar num ecrã secundário."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"A app não é compatível com o início em ecrãs secundários."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Divisor do ecrã dividido"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ecrã esquerdo inteiro"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70% no ecrã esquerdo"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% no ecrã esquerdo"</string>
@@ -72,7 +76,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..d3fb14d 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Configurações"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Dividir tela"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está em picture-in-picture"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Se você não quer que o app <xliff:g id="NAME">%s</xliff:g> use este recurso, toque para abrir as configurações e desativá-lo."</string>
     <string name="pip_play" msgid="3496151081459417097">"Reproduzir"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É possível que o app não funcione em uma tela secundária."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"O app não é compatível com a inicialização em telas secundárias."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Divisor de tela"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Lado esquerdo em tela cheia"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Esquerda a 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Esquerda a 50%"</string>
@@ -72,7 +76,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..7aaa21b 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Setări"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Accesați ecranul împărțit"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Meniu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> este în modul picture-in-picture"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Dacă nu doriți ca <xliff:g id="NAME">%s</xliff:g> să utilizeze această funcție, atingeți pentru a deschide setările și dezactivați-o."</string>
     <string name="pip_play" msgid="3496151081459417097">"Redați"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Este posibil ca aplicația să nu funcționeze pe un ecran secundar."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplicația nu acceptă lansare pe ecrane secundare."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Separator pentru ecranul împărțit"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Partea stângă pe ecran complet"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Partea stângă: 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Partea stângă: 50%"</string>
@@ -72,7 +76,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..7270449 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Настройки"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Включить разделение экрана"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> находится в режиме \"Картинка в картинке\""</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Чтобы отключить эту функцию для приложения \"<xliff:g id="NAME">%s</xliff:g>\", перейдите в настройки."</string>
     <string name="pip_play" msgid="3496151081459417097">"Воспроизвести"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Приложение может не работать на дополнительном экране"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Приложение не поддерживает запуск на дополнительных экранах"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Разделитель экрана"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Левый во весь экран"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Левый на 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Левый на 50%"</string>
@@ -72,7 +76,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..ef25c0a 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"සැකසීම්"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"බෙදුම් තිරයට ඇතුළු වන්න"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"මෙනුව"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> පින්තූරය-තුළ-පින්තූරය තුළ වේ"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"ඔබට <xliff:g id="NAME">%s</xliff:g> මෙම විශේෂාංගය භාවිත කිරීමට අවශ්‍ය නැති නම්, සැකසීම් විවෘත කිරීමට තට්ටු කර එය ක්‍රියාවිරහිත කරන්න."</string>
     <string name="pip_play" msgid="3496151081459417097">"ධාවනය කරන්න"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"යෙදුම ද්විතියික සංදර්ශකයක ක්‍රියා නොකළ හැකිය."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"යෙදුම ද්විතීයික සංදර්ශක මත දියත් කිරීම සඳහා සහාය නොදක්වයි."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"බෙදුම්-තිර වෙන්කරණය"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"වම් පූර්ණ තිරය"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"වම් 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"වම් 50%"</string>
@@ -72,7 +76,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..069bd1d2 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Nastavenia"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Prejsť na rozdelenú obrazovku"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Ponuka"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je v režime obraz v obraze"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Ak nechcete, aby aplikácia <xliff:g id="NAME">%s</xliff:g> používala túto funkciu, klepnutím otvorte nastavenia a vypnite ju."</string>
     <string name="pip_play" msgid="3496151081459417097">"Prehrať"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikácia nemusí fungovať na sekundárnej obrazovke."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikácia nepodporuje spúšťanie na sekundárnych obrazovkách."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Rozdeľovač obrazovky"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ľavá – na celú obrazovku"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Ľavá – 70 %"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ľavá – 50 %"</string>
@@ -72,7 +76,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..fe5813e 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Nastavitve"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Vklopi razdeljen zaslon"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Meni"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je v načinu slika v sliki"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Če ne želite, da aplikacija <xliff:g id="NAME">%s</xliff:g> uporablja to funkcijo, se dotaknite, da odprete nastavitve, in funkcijo izklopite."</string>
     <string name="pip_play" msgid="3496151081459417097">"Predvajaj"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija morda ne bo delovala na sekundarnem zaslonu."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podpira zagona na sekundarnih zaslonih."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Razdelilnik zaslonov"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Levi v celozaslonski način"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Levi 70 %"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Levi 50 %"</string>
@@ -72,7 +76,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..79c5334 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Cilësimet"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Hyr në ekranin e ndarë"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menyja"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> është në figurë brenda figurës"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Nëse nuk dëshiron që <xliff:g id="NAME">%s</xliff:g> ta përdorë këtë funksion, trokit për të hapur cilësimet dhe për ta çaktivizuar."</string>
     <string name="pip_play" msgid="3496151081459417097">"Luaj"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacioni mund të mos funksionojë në një ekran dytësor."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacioni nuk mbështet nisjen në ekrane dytësore."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Ndarësi i ekranit të ndarë"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ekrani i plotë majtas"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Majtas 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Majtas 50%"</string>
@@ -72,7 +76,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..a1b8e03 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Подешавања"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Уђи на подељени екран"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Мени"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> је слика у слици"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Ако не желите да <xliff:g id="NAME">%s</xliff:g> користи ову функцију, додирните да бисте отворили подешавања и искључили је."</string>
     <string name="pip_play" msgid="3496151081459417097">"Пусти"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апликација можда неће функционисати на секундарном екрану."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Апликација не подржава покретање на секундарним екранима."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Разделник подељеног екрана"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Режим целог екрана за леви екран"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Леви екран 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Леви екран 50%"</string>
@@ -72,7 +76,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..90e2acf 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Inställningar"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Starta delad skärm"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Meny"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> visas i bild-i-bild"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Om du inte vill att den här funktionen används i <xliff:g id="NAME">%s</xliff:g> öppnar du inställningarna genom att trycka. Sedan inaktiverar du funktionen."</string>
     <string name="pip_play" msgid="3496151081459417097">"Spela upp"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen kanske inte fungerar på en sekundär skärm."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan inte köras på en sekundär skärm."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Avdelare för delad skärm"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Helskärm på vänster skärm"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Vänster 70 %"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vänster 50 %"</string>
@@ -72,7 +76,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..b231ce0 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Mipangilio"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Weka skrini iliyogawanywa"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menyu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> iko katika hali ya picha ndani ya picha nyingine"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Ikiwa hutaki <xliff:g id="NAME">%s</xliff:g> itumie kipengele hiki, gusa ili ufungue mipangilio na uizime."</string>
     <string name="pip_play" msgid="3496151081459417097">"Cheza"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Huenda programu isifanye kazi kwenye dirisha lingine."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Programu hii haiwezi kufunguliwa kwenye madirisha mengine."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Kitenganishi cha skrini inayogawanywa"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Skrini nzima ya kushoto"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Kushoto 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kushoto 50%"</string>
@@ -72,7 +76,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..e12868b 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"அமைப்புகள்"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"திரைப் பிரிப்பு பயன்முறைக்குச் செல்"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"மெனு"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> தற்போது பிக்ச்சர்-இன்-பிக்ச்சரில் உள்ளது"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> இந்த அம்சத்தைப் பயன்படுத்த வேண்டாம் என நினைத்தால் இங்கு தட்டி அமைப்புகளைத் திறந்து இதை முடக்கவும்."</string>
     <string name="pip_play" msgid="3496151081459417097">"இயக்கு"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"இரண்டாம்நிலைத் திரையில் ஆப்ஸ் வேலை செய்யாமல் போகக்கூடும்."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"இரண்டாம்நிலைத் திரைகளில் பயன்பாட்டைத் தொடங்க முடியாது."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"திரையைப் பிரிக்கும் பிரிப்பான்"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"இடது புறம் முழுத் திரை"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"இடது புறம் 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"இடது புறம் 50%"</string>
@@ -72,7 +76,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..305229e 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"సెట్టింగ్‌లు"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"స్ప్లిట్ స్క్రీన్‌ను ఎంటర్ చేయండి"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"మెనూ"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> చిత్రంలో చిత్రం రూపంలో ఉంది"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> ఈ లక్షణాన్ని ఉపయోగించకూడదు అని మీరు అనుకుంటే, సెట్టింగ్‌లను తెరవడానికి ట్యాప్ చేసి, దీన్ని ఆఫ్ చేయండి."</string>
     <string name="pip_play" msgid="3496151081459417097">"ప్లే చేయి"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ప్రత్యామ్నాయ డిస్‌ప్లేలో యాప్ పని చేయకపోవచ్చు."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ప్రత్యామ్నాయ డిస్‌ప్లేల్లో ప్రారంభానికి యాప్ మద్దతు లేదు."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"విభజన స్క్రీన్ విభాగిని"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ఎడమవైపు ఫుల్-స్క్రీన్‌"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ఎడమవైపు 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ఎడమవైపు 50%"</string>
@@ -72,7 +76,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..ed7e75a 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"การตั้งค่า"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"เข้าสู่โหมดแบ่งหน้าจอ"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"เมนู"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ใช้การแสดงภาพซ้อนภาพ"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"หากคุณไม่ต้องการให้ <xliff:g id="NAME">%s</xliff:g> ใช้ฟีเจอร์นี้ ให้แตะเพื่อเปิดการตั้งค่าแล้วปิดฟีเจอร์"</string>
     <string name="pip_play" msgid="3496151081459417097">"เล่น"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"แอปอาจไม่ทำงานในจอแสดงผลรอง"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"แอปไม่รองรับการเรียกใช้ในจอแสดงผลรอง"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"เส้นแบ่งหน้าจอ"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"เต็มหน้าจอทางซ้าย"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ซ้าย 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ซ้าย 50%"</string>
@@ -72,7 +76,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..261bc74 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Mga Setting"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Pumasok sa split screen"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"Nasa picture-in-picture ang <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Kung ayaw mong magamit ni <xliff:g id="NAME">%s</xliff:g> ang feature na ito, i-tap upang buksan ang mga setting at i-off ito."</string>
     <string name="pip_play" msgid="3496151081459417097">"I-play"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Maaaring hindi gumana ang app sa pangalawang display."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Hindi sinusuportahan ng app ang paglulunsad sa mga pangalawang display."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Divider ng split-screen"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"I-full screen ang nasa kaliwa"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Gawing 70% ang nasa kaliwa"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Gawing 50% ang nasa kaliwa"</string>
@@ -72,7 +76,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..8c9b2c9 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Ayarlar"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Bölünmüş ekrana geç"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menü"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>, pencere içinde pencere özelliğini kullanıyor"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> uygulamasının bu özelliği kullanmasını istemiyorsanız dokunarak ayarları açın ve söz konusu özelliği kapatın."</string>
     <string name="pip_play" msgid="3496151081459417097">"Oynat"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Uygulama ikincil ekranda çalışmayabilir."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Uygulama ikincil ekranlarda başlatılmayı desteklemiyor."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Bölünmüş ekran ayırıcı"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Solda tam ekran"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Solda %70"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Solda %50"</string>
@@ -72,7 +76,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..db548eb 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Налаштування"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Розділити екран"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"У додатку <xliff:g id="NAME">%s</xliff:g> є функція \"Картинка в картинці\""</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Щоб додаток <xliff:g id="NAME">%s</xliff:g> не використовував цю функцію, вимкніть її в налаштуваннях."</string>
     <string name="pip_play" msgid="3496151081459417097">"Відтворити"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Додаток може не працювати на додатковому екрані."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Додаток не підтримує запуск на додаткових екранах."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Розділювач екрана"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ліве вікно на весь екран"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Ліве вікно на 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ліве вікно на 50%"</string>
@@ -72,7 +76,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..ea63e9d 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"ترتیبات"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"اسپلٹ اسکرین تک رسائی"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"مینو"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> تصویر میں تصویر میں ہے"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"اگر آپ نہیں چاہتے ہیں کہ <xliff:g id="NAME">%s</xliff:g> اس خصوصیت کا استعمال کرے تو ترتیبات کھولنے کے لیے تھپتھپا کر اسے آف کرے۔"</string>
     <string name="pip_play" msgid="3496151081459417097">"چلائیں"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ممکن ہے ایپ ثانوی ڈسپلے پر کام نہ کرے۔"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ایپ ثانوی ڈسپلیز پر شروعات کا تعاون نہیں کرتی۔"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"سپلٹ اسکرین تقسیم کار"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"بائیں فل اسکرین"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"بائیں %70"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"بائیں %50"</string>
@@ -72,7 +76,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..a334b0e 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Sozlamalar"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Ajratilgan ekranga kirish"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menyu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> tasvir ustida tasvir rejimida"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> ilovasi uchun bu funksiyani sozlamalar orqali faolsizlantirish mumkin."</string>
     <string name="pip_play" msgid="3496151081459417097">"Ijro"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Bu ilova qo‘shimcha ekranda ishlamasligi mumkin."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Bu ilova qo‘shimcha ekranlarda ishga tushmaydi."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Ekranni ikkiga bo‘lish chizig‘i"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Chapda to‘liq ekran"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Chapda 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Chapda 50%"</string>
@@ -72,7 +76,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..03f500a 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Cài đặt"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Truy cập chế độ chia đôi màn hình"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> đang ở chế độ ảnh trong ảnh"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Nếu bạn không muốn <xliff:g id="NAME">%s</xliff:g> sử dụng tính năng này, hãy nhấn để mở cài đặt và tắt tính năng này."</string>
     <string name="pip_play" msgid="3496151081459417097">"Phát"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Ứng dụng có thể không hoạt động trên màn hình phụ."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Ứng dụng không hỗ trợ khởi chạy trên màn hình phụ."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Bộ chia chia đôi màn hình"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Toàn màn hình bên trái"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Trái 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Trái 50%"</string>
@@ -72,7 +76,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..2b04f6e 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"设置"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"进入分屏模式"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"菜单"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>目前位于“画中画”中"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"如果您不想让“<xliff:g id="NAME">%s</xliff:g>”使用此功能,请点按以打开设置,然后关闭此功能。"</string>
     <string name="pip_play" msgid="3496151081459417097">"播放"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"应用可能无法在辅显示屏上正常运行。"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"应用不支持在辅显示屏上启动。"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"分屏分隔线"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"左侧全屏"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"左侧 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"左侧 50%"</string>
@@ -72,7 +76,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..253869b 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"設定"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"進入分割螢幕"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"選單"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"「<xliff:g id="NAME">%s</xliff:g>」目前在畫中畫模式"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"如果您不想「<xliff:g id="NAME">%s</xliff:g>」使用此功能,請輕按以開啟設定,然後停用此功能。"</string>
     <string name="pip_play" msgid="3496151081459417097">"播放"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"應用程式可能無法在次要顯示屏上運作。"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"應用程式無法在次要顯示屏上啟動。"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"分割畫面分隔線"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"左邊全螢幕"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"左邊 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"左邊 50%"</string>
@@ -72,7 +76,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..6109cbb 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"設定"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"進入分割畫面"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"選單"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"「<xliff:g id="NAME">%s</xliff:g>」目前在子母畫面中"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"如果你不想讓「<xliff:g id="NAME">%s</xliff:g>」使用這項功能,請輕觸開啟設定頁面,然後停用此功能。"</string>
     <string name="pip_play" msgid="3496151081459417097">"播放"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"應用程式可能無法在次要顯示器上運作。"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"應用程式無法在次要顯示器上啟動。"</string>
     <string name="accessibility_divider" msgid="703810061635792791">"分割畫面分隔線"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"以全螢幕顯示左側畫面"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"以 70% 的螢幕空間顯示左側畫面"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"以 50% 的螢幕空間顯示左側畫面"</string>
@@ -72,7 +76,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..8af4f9f 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -22,6 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Izilungiselelo"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Faka ukuhlukanisa isikrini"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Imenyu"</string>
+    <!-- no translation found for pip_menu_accessibility_title (8129016817688656249) -->
+    <skip />
     <string name="pip_notification_title" msgid="1347104727641353453">"U-<xliff:g id="NAME">%s</xliff:g> ungaphakathi kwesithombe esiphakathi kwesithombe"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Uma ungafuni i-<xliff:g id="NAME">%s</xliff:g> ukuthi isebenzise lesi sici, thepha ukuze uvule izilungiselelo uphinde uyivale."</string>
     <string name="pip_play" msgid="3496151081459417097">"Dlala"</string>
@@ -36,6 +38,8 @@
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Uhlelo lokusebenza kungenzeka lungasebenzi kusibonisi sesibili."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Uhlelo lokusebenza alusekeli ukuqalisa kuzibonisi zesibili."</string>
     <string name="accessibility_divider" msgid="703810061635792791">"Isihlukanisi sokuhlukanisa isikrini"</string>
+    <!-- no translation found for divider_title (5482989479865361192) -->
+    <skip />
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Isikrini esigcwele esingakwesokunxele"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Kwesokunxele ngo-70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kwesokunxele ngo-50%"</string>
@@ -72,7 +76,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/ShellCommandHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java
deleted file mode 100644
index 73fd693..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.wm.shell;
-
-import com.android.wm.shell.common.annotations.ExternalThread;
-
-import java.io.PrintWriter;
-
-/**
- * An entry point into the shell for dumping shell internal state and running adb commands.
- *
- * Use with {@code adb shell dumpsys activity service SystemUIService WMShell ...}.
- */
-@ExternalThread
-public interface ShellCommandHandler {
-    /**
-     * Dumps the shell state.
-     */
-    void dump(PrintWriter pw);
-
-    /**
-     * Handles a shell command.
-     */
-    boolean handleCommand(final String[] args, PrintWriter pw);
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java
deleted file mode 100644
index d7010b1..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.wm.shell;
-
-import com.android.wm.shell.common.annotations.ExternalThread;
-
-/**
- * An entry point into the shell for initializing shell internal state.
- */
-@ExternalThread
-public interface ShellInit {
-    /**
-     * Initializes the shell state.
-     */
-    void init();
-}
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/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
index 6fb021e..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,6 +50,8 @@
 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.
  */
@@ -212,7 +214,7 @@
                 newBounds.height() / 2 - mIconSize / 2);
 
         if (animate) {
-            startFadeAnimation(show, false /* isResized */);
+            startFadeAnimation(show, null /* finishedConsumer */);
             mShown = show;
         }
     }
@@ -243,15 +245,29 @@
             mFadeAnimator.cancel();
         }
         if (mShown) {
-            startFadeAnimation(false /* show */, true /* isResized */);
-            mShown = false;
+            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);
@@ -285,8 +301,8 @@
                         animT.hide(mIconLeash);
                     }
                 }
-                if (isResized) {
-                    releaseDecor(animT);
+                if (finishedConsumer != null) {
+                    finishedConsumer.accept(animT);
                 }
                 animT.apply();
                 animT.close();
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 5801d43..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;
@@ -449,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,
@@ -487,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) {
@@ -704,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);
@@ -746,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..f85f9d6 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
@@ -29,15 +29,14 @@
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.RootDisplayAreaOrganizer;
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
-import com.android.wm.shell.ShellCommandHandler;
-import com.android.wm.shell.ShellCommandHandlerImpl;
-import com.android.wm.shell.ShellInit;
-import com.android.wm.shell.ShellInitImpl;
+import com.android.wm.shell.sysui.ShellCommandHandler;
+import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.TaskViewFactory;
 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 +55,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 +78,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 +155,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 +194,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 +358,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 +392,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,19 +588,43 @@
                 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
     //
 
     @WMSingleton
     @Provides
-    static ShellInit provideShellInit(ShellInitImpl impl) {
-        return impl.asShellInit();
-    }
-
-    @WMSingleton
-    @Provides
-    static ShellInitImpl provideShellInitImpl(DisplayController displayController,
+    static ShellInit provideShellInitImpl(
+            ShellController shellController,
+            DisplayController displayController,
             DisplayImeController displayImeController,
             DisplayInsetsController displayInsetsController,
             DragAndDropController dragAndDropController,
@@ -647,10 +638,12 @@
             Optional<UnfoldTransitionHandler> unfoldTransitionHandler,
             Optional<FreeformTaskListener<?>> freeformTaskListener,
             Optional<RecentTasksController> recentTasksOptional,
+            Optional<ActivityEmbeddingController> activityEmbeddingOptional,
             Transitions transitions,
             StartingWindowController startingWindow,
             @ShellMainThread ShellExecutor mainExecutor) {
-        return new ShellInitImpl(displayController,
+        return new ShellInit(shellController,
+                displayController,
                 displayImeController,
                 displayInsetsController,
                 dragAndDropController,
@@ -664,24 +657,16 @@
                 unfoldTransitionHandler,
                 freeformTaskListener,
                 recentTasksOptional,
+                activityEmbeddingOptional,
                 transitions,
                 startingWindow,
                 mainExecutor);
     }
 
-    /**
-     * Note, this is only optional because we currently pass this to the SysUI component scope and
-     * for non-primary users, we may inject a null-optional for that dependency.
-     */
     @WMSingleton
     @Provides
-    static Optional<ShellCommandHandler> provideShellCommandHandler(ShellCommandHandlerImpl impl) {
-        return Optional.of(impl.asShellCommandHandler());
-    }
-
-    @WMSingleton
-    @Provides
-    static ShellCommandHandlerImpl provideShellCommandHandlerImpl(
+    static ShellCommandHandler provideShellCommandHandlerImpl(
+            ShellController shellController,
             ShellTaskOrganizer shellTaskOrganizer,
             KidsModeTaskOrganizer kidsModeTaskOrganizer,
             Optional<SplitScreenController> splitScreenOptional,
@@ -690,9 +675,9 @@
             Optional<HideDisplayCutoutController> hideDisplayCutout,
             Optional<RecentTasksController> recentTasksOptional,
             @ShellMainThread ShellExecutor mainExecutor) {
-        return new ShellCommandHandlerImpl(shellTaskOrganizer, kidsModeTaskOrganizer,
-                splitScreenOptional, pipOptional, oneHandedOptional, hideDisplayCutout,
-                recentTasksOptional, mainExecutor);
+        return new ShellCommandHandler(shellController, shellTaskOrganizer,
+                kidsModeTaskOrganizer, splitScreenOptional, pipOptional, oneHandedOptional,
+                hideDisplayCutout, recentTasksOptional, mainExecutor);
     }
 
     @WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java
index cc741d3..35a309a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java
@@ -27,6 +27,7 @@
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Trace;
+import android.view.Choreographer;
 
 import androidx.annotation.Nullable;
 
@@ -144,6 +145,25 @@
     }
 
     /**
+     * Provide a Shell main-thread {@link Choreographer} with the app vsync.
+     *
+     * @param executor the executor of the shell main thread
+     */
+    @WMSingleton
+    @Provides
+    @ShellMainThread
+    public static Choreographer provideShellMainChoreographer(
+            @ShellMainThread ShellExecutor executor) {
+        try {
+            final Choreographer[] choreographer = new Choreographer[1];
+            executor.executeBlocking(() -> choreographer[0] = Choreographer.getInstance());
+            return choreographer[0];
+        } catch (InterruptedException e) {
+            throw new RuntimeException("Failed to obtain main Choreographer.", e);
+        }
+    }
+
+    /**
      * Provide a Shell animation-thread Executor.
      */
     @WMSingleton
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..0dc293b 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
@@ -20,6 +20,7 @@
 import android.content.pm.LauncherApps;
 import android.os.Handler;
 import android.os.UserManager;
+import android.view.Choreographer;
 import android.view.WindowManager;
 
 import com.android.internal.jank.InteractionJankMonitor;
@@ -31,6 +32,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 +72,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 +110,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 +145,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 +156,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);
     }
 
@@ -142,12 +174,14 @@
     static WindowDecorViewModel<?> provideWindowDecorViewModel(
             Context context,
             @ShellMainThread Handler mainHandler,
+            @ShellMainThread Choreographer mainChoreographer,
             ShellTaskOrganizer taskOrganizer,
             DisplayController displayController,
             SyncTransactionQueue syncQueue) {
         return new CaptionWindowDecorViewModel(
                         context,
                         mainHandler,
+                        mainChoreographer,
                         taskOrganizer,
                         displayController,
                         syncQueue);
@@ -176,12 +210,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 +228,7 @@
     @Provides
     @DynamicOverride
     static SplitScreenController provideSplitScreenController(
+            ShellController shellController,
             ShellTaskOrganizer shellTaskOrganizer,
             SyncTransactionQueue syncQueue, Context context,
             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
@@ -201,7 +238,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 +250,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 +263,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/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 c6f7974..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,8 +193,8 @@
     }
 
     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) {
@@ -572,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/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 046b1a2..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,8 +18,6 @@
 
 import static android.app.ActivityManager.START_SUCCESS;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 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;
@@ -82,6 +80,8 @@
 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;
 
@@ -101,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>, ShellTaskOrganizer.FocusListener {
+        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,
@@ -129,6 +129,7 @@
     @Retention(RetentionPolicy.SOURCE)
     @interface ExitReason{}
 
+    private final ShellController mShellController;
     private final ShellTaskOrganizer mTaskOrganizer;
     private final SyncTransactionQueue mSyncQueue;
     private final Context mContext;
@@ -149,9 +150,8 @@
     // outside the bounds of the roots by being reparented into a higher level fullscreen container
     private SurfaceControl mSplitTasksContainerLayer;
 
-    private ActivityManager.RunningTaskInfo mFocusingTaskInfo;
-
-    public SplitScreenController(ShellTaskOrganizer shellTaskOrganizer,
+    public SplitScreenController(ShellController shellController,
+            ShellTaskOrganizer shellTaskOrganizer,
             SyncTransactionQueue syncQueue, Context context,
             RootTaskDisplayAreaOrganizer rootTDAOrganizer,
             ShellExecutor mainExecutor, DisplayController displayController,
@@ -159,6 +159,7 @@
             DisplayInsetsController displayInsetsController,
             Transitions transitions, TransactionPool transactionPool, IconProvider iconProvider,
             Optional<RecentTasksController> recentTasks) {
+        mShellController = shellController;
         mTaskOrganizer = shellTaskOrganizer;
         mSyncQueue = syncQueue;
         mContext = context;
@@ -172,7 +173,6 @@
         mLogger = new SplitscreenEventLogger();
         mIconProvider = iconProvider;
         mRecentTasksOptional = recentTasks;
-        mTaskOrganizer.addFocusListener(this);
     }
 
     public SplitScreen asSplitScreen() {
@@ -189,12 +189,8 @@
         return mMainExecutor;
     }
 
-    @Override
-    public void onFocusTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
-        mFocusingTaskInfo = taskInfo;
-    }
-
     public void onOrganizerRegistered() {
+        mShellController.addKeyguardChangeListener(this);
         if (mStageCoordinator == null) {
             // TODO: Multi-display
             mStageCoordinator = new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
@@ -212,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) {
@@ -285,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() {
@@ -463,12 +469,9 @@
             return Objects.equals(launchingActivity, pairedActivity);
         }
 
-        if (mFocusingTaskInfo != null
-                // TODO (b/238032411): have an API to determine whether an activity is valid for
-                //  split screen or not.
-                && mFocusingTaskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
-                && mFocusingTaskInfo.getActivityType() == ACTIVITY_TYPE_STANDARD) {
-            return Objects.equals(mFocusingTaskInfo.baseIntent.getComponent(), launchingActivity);
+        final ActivityManager.RunningTaskInfo taskInfo = getFocusingTaskInfo();
+        if (taskInfo != null && isValidToEnterSplitScreen(taskInfo)) {
+            return Objects.equals(taskInfo.baseIntent.getComponent(), launchingActivity);
         }
 
         return false;
@@ -486,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,
@@ -655,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 55e7dac..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();
 
@@ -174,6 +179,8 @@
     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.
      */
@@ -187,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. */
@@ -252,6 +260,7 @@
         mDisplayController.addDisplayWindowListener(this);
         mDisplayLayout = new DisplayLayout(displayController.getDisplayLayout(displayId));
         transitions.addHandler(this);
+        mTaskOrganizer.addFocusListener(this);
     }
 
     @VisibleForTesting
@@ -440,7 +449,7 @@
                         new IRemoteAnimationFinishedCallback.Stub() {
                             @Override
                             public void onAnimationFinished() throws RemoteException {
-                                onRemoteAnimationFinishedOrCancelled(evictWct);
+                                onRemoteAnimationFinishedOrCancelled(false /* cancel */, evictWct);
                                 finishedCallback.onAnimationFinished();
                             }
                         };
@@ -461,7 +470,7 @@
 
             @Override
             public void onAnimationCancelled(boolean isKeyguardOccluded) {
-                onRemoteAnimationFinishedOrCancelled(evictWct);
+                onRemoteAnimationFinishedOrCancelled(true /* cancel */, evictWct);
                 try {
                     adapter.getRunner().onAnimationCancelled(isKeyguardOccluded);
                 } catch (RemoteException e) {
@@ -511,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));
@@ -731,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
@@ -743,21 +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 -> {
             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) {
@@ -927,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() {
@@ -1024,6 +1060,7 @@
         }
 
         mRootTaskInfo = null;
+        mRootTaskLeash = null;
     }
 
 
@@ -1174,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;
@@ -1203,13 +1261,28 @@
         }
     }
 
+    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;
         }
 
@@ -1531,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
@@ -1611,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();
@@ -1907,8 +1980,8 @@
         }
 
         @Override
-        public void onChildTaskEnterPip(int taskId) {
-            StageCoordinator.this.onStageChildTaskEnterPip(this, taskId);
+        public void onChildTaskEnterPip() {
+            StageCoordinator.this.onStageChildTaskEnterPip();
         }
 
         @Override
@@ -1920,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;
                 }
 
@@ -1932,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 99e7506..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();
     }
@@ -212,12 +212,15 @@
             }
             mRootTaskInfo = taskInfo;
         } else if (taskInfo.parentTaskId == mRootTaskInfo.taskId) {
-            if (!taskInfo.supportsMultiWindow) {
-                // Leave split screen if the task no longer supports multi window.
+            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);
@@ -243,6 +246,7 @@
         if (mRootTaskInfo.taskId == taskId) {
             mCallbacks.onRootTaskVanished();
             mRootTaskInfo = null;
+            mRootLeash = null;
             mSyncQueue.runInSync(t -> {
                 t.remove(mDimLayer);
                 mSplitDecorManager.release(t);
@@ -256,7 +260,7 @@
                 return;
             }
             if (taskInfo.getWindowingMode() == WINDOWING_MODE_PINNED) {
-                mCallbacks.onChildTaskEnterPip(taskId);
+                mCallbacks.onChildTaskEnterPip();
             }
             sendStatusChanged();
         } else {
@@ -298,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.
@@ -331,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/ShellCommandHandlerImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellCommandHandler.java
similarity index 82%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellCommandHandler.java
index c5f7c19..0427efb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellCommandHandler.java
@@ -14,10 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell;
+package com.android.wm.shell.sysui;
 
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
 
+import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController;
 import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer;
@@ -34,8 +35,8 @@
  *
  * Use with {@code adb shell dumpsys activity service SystemUIService WMShell ...}.
  */
-public final class ShellCommandHandlerImpl {
-    private static final String TAG = ShellCommandHandlerImpl.class.getSimpleName();
+public final class ShellCommandHandler {
+    private static final String TAG = ShellCommandHandler.class.getSimpleName();
 
     private final Optional<SplitScreenController> mSplitScreenOptional;
     private final Optional<Pip> mPipOptional;
@@ -45,9 +46,9 @@
     private final ShellTaskOrganizer mShellTaskOrganizer;
     private final KidsModeTaskOrganizer mKidsModeTaskOrganizer;
     private final ShellExecutor mMainExecutor;
-    private final HandlerImpl mImpl = new HandlerImpl();
 
-    public ShellCommandHandlerImpl(
+    public ShellCommandHandler(
+            ShellController shellController,
             ShellTaskOrganizer shellTaskOrganizer,
             KidsModeTaskOrganizer kidsModeTaskOrganizer,
             Optional<SplitScreenController> splitScreenOptional,
@@ -64,14 +65,12 @@
         mOneHandedOptional = oneHandedOptional;
         mHideDisplayCutout = hideDisplayCutout;
         mMainExecutor = mainExecutor;
-    }
-
-    public ShellCommandHandler asShellCommandHandler() {
-        return mImpl;
+        // TODO(238217847): To be removed once the command handler dependencies are inverted
+        shellController.setShellCommandHandler(this);
     }
 
     /** Dumps WM Shell internal state. */
-    private void dump(PrintWriter pw) {
+    public void dump(PrintWriter pw) {
         mShellTaskOrganizer.dump(pw, "");
         pw.println();
         pw.println();
@@ -91,7 +90,7 @@
 
 
     /** Returns {@code true} if command was found and executed. */
-    private boolean handleCommand(final String[] args, PrintWriter pw) {
+    public boolean handleCommand(final String[] args, PrintWriter pw) {
         if (args.length < 2) {
             // Argument at position 0 is "WMShell".
             return false;
@@ -164,28 +163,4 @@
         pw.println("    Sets the position of the side-stage.");
         return true;
     }
-
-    private class HandlerImpl implements ShellCommandHandler {
-        @Override
-        public void dump(PrintWriter pw) {
-            try {
-                mMainExecutor.executeBlocking(() -> ShellCommandHandlerImpl.this.dump(pw));
-            } catch (InterruptedException e) {
-                throw new RuntimeException("Failed to dump the Shell in 2s", e);
-            }
-        }
-
-        @Override
-        public boolean handleCommand(String[] args, PrintWriter pw) {
-            try {
-                boolean[] result = new boolean[1];
-                mMainExecutor.executeBlocking(() -> {
-                    result[0] = ShellCommandHandlerImpl.this.handleCommand(args, pw);
-                });
-                return result[0];
-            } catch (InterruptedException e) {
-                throw new RuntimeException("Failed to handle Shell command in 2s", e);
-            }
-        }
-    }
 }
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..618028c
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java
@@ -0,0 +1,240 @@
+/*
+ * 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 ShellInit mShellInit;
+    private ShellCommandHandler mShellCommandHandler;
+
+    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;
+    }
+
+    /**
+     * Sets the init handler to call back to.
+     * TODO(238217847): This is only exposed this way until we can remove the dependencies from the
+     *                  init handler to other classes.
+     */
+    public void setShellInit(ShellInit shellInit) {
+        mShellInit = shellInit;
+    }
+
+    /**
+     * Sets the command handler to call back to.
+     * TODO(238217847): This is only exposed this way until we can remove the dependencies from the
+     *                  command handler to other classes.
+     */
+    public void setShellCommandHandler(ShellCommandHandler shellCommandHandler) {
+        mShellCommandHandler = shellCommandHandler;
+    }
+
+    /**
+     * 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 onInit() {
+            try {
+                mMainExecutor.executeBlocking(() -> mShellInit.init());
+            } catch (InterruptedException e) {
+                throw new RuntimeException("Failed to initialize the Shell in 2s", e);
+            }
+        }
+
+        @Override
+        public void dump(PrintWriter pw) {
+            try {
+                mMainExecutor.executeBlocking(() -> mShellCommandHandler.dump(pw));
+            } catch (InterruptedException e) {
+                throw new RuntimeException("Failed to dump the Shell in 2s", e);
+            }
+        }
+
+        @Override
+        public boolean handleCommand(String[] args, PrintWriter pw) {
+            try {
+                boolean[] result = new boolean[1];
+                mMainExecutor.executeBlocking(() -> {
+                    result[0] = mShellCommandHandler.handleCommand(args, pw);
+                });
+                return result[0];
+            } catch (InterruptedException e) {
+                throw new RuntimeException("Failed to handle Shell command in 2s", e);
+            }
+        }
+
+        @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/ShellInitImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
similarity index 69%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
index 992f315..2619b37 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
@@ -14,16 +14,25 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell;
+package com.android.wm.shell.sysui;
 
 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.ShellTaskOrganizer;
+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.common.annotations.ExternalThread;
 import com.android.wm.shell.draganddrop.DragAndDropController;
 import com.android.wm.shell.freeform.FreeformTaskListener;
 import com.android.wm.shell.fullscreen.FullscreenTaskListener;
@@ -37,13 +46,15 @@
 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();
+public class ShellInit {
+    private static final String TAG = ShellInit.class.getSimpleName();
 
     private final DisplayController mDisplayController;
     private final DisplayImeController mDisplayImeController;
@@ -62,10 +73,14 @@
     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(
+    public ShellInit(
+            ShellController shellController,
             DisplayController displayController,
             DisplayImeController displayImeController,
             DisplayInsetsController displayInsetsController,
@@ -80,6 +95,7 @@
             Optional<UnfoldTransitionHandler> unfoldTransitionHandler,
             Optional<FreeformTaskListener<?>> freeformTaskListenerOptional,
             Optional<RecentTasksController> recentTasks,
+            Optional<ActivityEmbeddingController> activityEmbeddingOptional,
             Transitions transitions,
             StartingWindowController startingWindow,
             ShellExecutor mainExecutor) {
@@ -97,16 +113,15 @@
         mUnfoldTransitionHandler = unfoldTransitionHandler;
         mFreeformTaskListenerOptional = freeformTaskListenerOptional;
         mRecentTasks = recentTasks;
+        mActivityEmbeddingOptional = activityEmbeddingOptional;
         mTransitions = transitions;
         mMainExecutor = mainExecutor;
         mStartingWindow = startingWindow;
+        // TODO(238217847): To be removed once the init dependencies are inverted
+        shellController.setShellInit(this);
     }
 
-    public ShellInit asShellInit() {
-        return mImpl;
-    }
-
-    private void init() {
+    private void legacyInit() {
         // Start listening for display and insets changes
         mDisplayController.initialize();
         mDisplayInsetsController.initialize();
@@ -126,6 +141,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,15 +169,43 @@
         mKidsModeTaskOrganizer.initialize(mStartingWindow);
     }
 
-    @ExternalThread
-    private class InitImpl implements ShellInit {
-        @Override
-        public void init() {
-            try {
-                mMainExecutor.executeBlocking(() -> ShellInitImpl.this.init());
-            } catch (InterruptedException e) {
-                throw new RuntimeException("Failed to initialize the Shell in 2s", e);
+    /**
+     * 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;
     }
 }
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..254c253
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInterface.java
@@ -0,0 +1,62 @@
+/*
+ * 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;
+
+import java.io.PrintWriter;
+
+/**
+ * General interface for notifying the Shell of common SysUI events like configuration or keyguard
+ * changes.
+ */
+public interface ShellInterface {
+
+    /**
+     * Initializes the shell state.
+     */
+    default void onInit() {}
+
+    /**
+     * Dumps the shell state.
+     */
+    default void dump(PrintWriter pw) {}
+
+    /**
+     * Handles a shell command.
+     */
+    default boolean handleCommand(final String[] args, PrintWriter pw) {
+        return false;
+    }
+
+    /**
+     * 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/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index 6d28d73..fe3724b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -25,6 +25,7 @@
 import android.app.ActivityTaskManager;
 import android.content.Context;
 import android.os.Handler;
+import android.view.Choreographer;
 import android.view.MotionEvent;
 import android.view.SurfaceControl;
 import android.view.View;
@@ -45,17 +46,20 @@
     private final ShellTaskOrganizer mTaskOrganizer;
     private final Context mContext;
     private final Handler mMainHandler;
+    private final Choreographer mMainChoreographer;
     private final DisplayController mDisplayController;
     private final SyncTransactionQueue mSyncQueue;
 
     public CaptionWindowDecorViewModel(
             Context context,
             Handler mainHandler,
+            Choreographer mainChoreographer,
             ShellTaskOrganizer taskOrganizer,
             DisplayController displayController,
             SyncTransactionQueue syncQueue) {
         mContext = context;
         mMainHandler = mainHandler;
+        mMainChoreographer = mainChoreographer;
         mActivityTaskManager = mContext.getSystemService(ActivityTaskManager.class);
         mTaskOrganizer = taskOrganizer;
         mDisplayController = displayController;
@@ -72,6 +76,7 @@
                 taskInfo,
                 taskSurface,
                 mMainHandler,
+                mMainChoreographer,
                 mSyncQueue);
         TaskPositioner taskPositioner = new TaskPositioner(mTaskOrganizer, windowDecoration);
         CaptionTouchEventListener touchEventListener =
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 cdca051..2df7104 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
@@ -25,6 +25,7 @@
 import android.graphics.drawable.GradientDrawable;
 import android.graphics.drawable.VectorDrawable;
 import android.os.Handler;
+import android.view.Choreographer;
 import android.view.SurfaceControl;
 import android.view.View;
 import android.window.WindowContainerTransaction;
@@ -59,6 +60,7 @@
             RESIZE_HANDLE_IN_DIP, RESIZE_HANDLE_IN_DIP, RESIZE_HANDLE_IN_DIP, RESIZE_HANDLE_IN_DIP);
 
     private final Handler mHandler;
+    private final Choreographer mChoreographer;
     private final SyncTransactionQueue mSyncQueue;
 
     private View.OnClickListener mOnCaptionButtonClickListener;
@@ -77,10 +79,12 @@
             ActivityManager.RunningTaskInfo taskInfo,
             SurfaceControl taskSurface,
             Handler handler,
+            Choreographer choreographer,
             SyncTransactionQueue syncQueue) {
         super(context, displayController, taskOrganizer, taskInfo, taskSurface);
 
         mHandler = handler;
+        mChoreographer = choreographer;
         mSyncQueue = syncQueue;
     }
 
@@ -138,6 +142,7 @@
             mDragResizeListener = new DragResizeInputListener(
                     mContext,
                     mHandler,
+                    mChoreographer,
                     mDisplay.getDisplayId(),
                     mDecorationContainerSurface,
                     mDragResizeCallback);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index c6bbb02..f512b0d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -27,8 +27,8 @@
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.RemoteException;
+import android.view.Choreographer;
 import android.view.IWindowSession;
 import android.view.InputChannel;
 import android.view.InputEvent;
@@ -49,6 +49,7 @@
 
     private final IWindowSession mWindowSession = WindowManagerGlobal.getWindowSession();
     private final Handler mHandler;
+    private final Choreographer mChoreographer;
     private final InputManager mInputManager;
 
     private final int mDisplayId;
@@ -68,11 +69,13 @@
     DragResizeInputListener(
             Context context,
             Handler handler,
+            Choreographer choreographer,
             int displayId,
             SurfaceControl decorationSurface,
             DragResizeCallback callback) {
         mInputManager = context.getSystemService(InputManager.class);
         mHandler = handler;
+        mChoreographer = choreographer;
         mDisplayId = displayId;
         mDecorationSurface = decorationSurface;
         // Use a fake window as the backing surface is a container layer and we don't want to create
@@ -97,7 +100,8 @@
             e.rethrowFromSystemServer();
         }
 
-        mInputEventReceiver = new TaskResizeInputEventReceiver(mInputChannel, mHandler.getLooper());
+        mInputEventReceiver = new TaskResizeInputEventReceiver(
+                mInputChannel, mHandler, mChoreographer);
         mCallback = callback;
     }
 
@@ -154,10 +158,6 @@
         } catch (RemoteException e) {
             e.rethrowFromSystemServer();
         }
-
-        // This marks all relevant components have handled the previous resize event and can take
-        // the next one now.
-        mInputEventReceiver.onHandledLastResizeEvent();
     }
 
     @Override
@@ -171,28 +171,39 @@
     }
 
     private class TaskResizeInputEventReceiver extends InputEventReceiver {
-        private boolean mWaitingForLastResizeEventHandled;
+        private final Choreographer mChoreographer;
+        private final Runnable mConsumeBatchEventRunnable;
+        private boolean mConsumeBatchEventScheduled;
 
-        private TaskResizeInputEventReceiver(InputChannel inputChannel, Looper looper) {
-            super(inputChannel, looper);
-        }
+        private TaskResizeInputEventReceiver(
+                InputChannel inputChannel, Handler handler, Choreographer choreographer) {
+            super(inputChannel, handler.getLooper());
+            mChoreographer = choreographer;
 
-        private void onHandledLastResizeEvent() {
-            mWaitingForLastResizeEventHandled = false;
-            consumeBatchedInputEvents(-1);
+            mConsumeBatchEventRunnable = () -> {
+                mConsumeBatchEventScheduled = false;
+                if (consumeBatchedInputEvents(mChoreographer.getFrameTimeNanos())) {
+                    // If we consumed a batch here, we want to go ahead and schedule the
+                    // consumption of batched input events on the next frame. Otherwise, we would
+                    // wait until we have more input events pending and might get starved by other
+                    // things occurring in the process.
+                    scheduleConsumeBatchEvent();
+                }
+            };
         }
 
         @Override
         public void onBatchedInputEventPending(int source) {
-            // InputEventReceiver keeps continuous move events in a batched event until explicitly
-            // consuming it or an incompatible event shows up (likely an up event in this case). We
-            // continue to keep move events in the next batched event until we receive a geometry
-            // update so that we don't put too much pressure on the framework with excessive number
-            // of input events if it can't handle them fast enough. It's more responsive to always
-            // resize the task to the latest received coordinates.
-            if (!mWaitingForLastResizeEventHandled) {
-                consumeBatchedInputEvents(-1);
+            scheduleConsumeBatchEvent();
+        }
+
+        private void scheduleConsumeBatchEvent() {
+            if (mConsumeBatchEventScheduled) {
+                return;
             }
+            mChoreographer.postCallback(
+                    Choreographer.CALLBACK_INPUT, mConsumeBatchEventRunnable, null);
+            mConsumeBatchEventScheduled = true;
         }
 
         @Override
@@ -211,14 +222,12 @@
                     mDragPointerId = e.getPointerId(0);
                     mCallback.onDragResizeStart(
                             calculateCtrlType(e.getX(0), e.getY(0)), e.getRawX(0), e.getRawY(0));
-                    mWaitingForLastResizeEventHandled = false;
                     break;
                 }
                 case MotionEvent.ACTION_MOVE: {
                     int dragPointerIndex = e.findPointerIndex(mDragPointerId);
                     mCallback.onDragResizeMove(
                             e.getRawX(dragPointerIndex), e.getRawY(dragPointerIndex));
-                    mWaitingForLastResizeEventHandled = true;
                     break;
                 }
                 case MotionEvent.ACTION_UP:
@@ -226,7 +235,6 @@
                     int dragPointerIndex = e.findPointerIndex(mDragPointerId);
                     mCallback.onDragResizeEnd(
                             e.getRawX(dragPointerIndex), e.getRawY(dragPointerIndex));
-                    mWaitingForLastResizeEventHandled = false;
                     mDragPointerId = -1;
                     break;
                 }
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..293eb7c 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,44 @@
     @Presubmit
     @Test
     fun testAppIsVisibleAtEnd() {
-        Assume.assumeFalse(isShellTransitionsEnabled)
         testSpec.assertLayersEnd {
-            this.isVisible(testApp.component)
+            this.isVisible(testApp)
         }
     }
 
+    /** {@inheritDoc} */
     @FlakyTest
     @Test
-    fun testAppIsVisibleAtEnd_ShellTransit() {
-        Assume.assumeTrue(isShellTransitionsEnabled)
-        testSpec.assertLayersEnd {
-            this.isVisible(testApp.component)
-        }
-    }
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @FlakyTest(bugId = 206753786)
+    @Test
+    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 48f9a7e..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
@@ -149,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"
         }
@@ -196,7 +196,7 @@
         uiDevice.click(expandButtonBounds.centerX(), expandButtonBounds.centerY())
         wmHelper.StateSyncBuilder()
             .withPipGone()
-            .withFullScreenApp(component)
+            .withFullScreenApp(this)
             .waitForAndVerify()
     }
 
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
index 2b6c0da..87fa548 100644
--- 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
@@ -16,9 +16,9 @@
 
 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.launcher3.tapl.LauncherInstrumentation
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.annotation.Group3
@@ -51,10 +51,9 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Postsubmit
+@FlakyTest(bugId = 238367575)
 @Group3
 class AutoEnterPipOnGoToHomeTest(testSpec: FlickerTestParameter) : EnterPipTest(testSpec) {
-    protected val taplInstrumentation = LauncherInstrumentation()
     /**
      * Defines the transition used to run the test
      */
@@ -75,14 +74,14 @@
                 }
             }
             transitions {
-                taplInstrumentation.goHome()
+                tapl.goHome()
             }
         }
 
+    @Test
     override 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.notBiggerThan(previous.visibleRegion.region)
             }
@@ -96,9 +95,8 @@
     fun pipLayerMovesTowardsRightBottomCorner() {
         // in gestural nav the swipe makes PiP first go upwards
         Assume.assumeFalse(testSpec.isGesturalNavigation)
-        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 }
             // 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
@@ -108,9 +106,66 @@
         }
     }
 
+    @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 9b12e2a..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
@@ -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..0450224 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(bugId = 239807171)
     @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)
         }
     }
@@ -115,10 +113,10 @@
      * Checks that the pip app layer remains inside the display bounds throughout the whole
      * animation
      */
-    @Presubmit
+    @FlakyTest(bugId = 239807171)
     @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/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/ShellInitTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellInitTest.java
new file mode 100644
index 0000000..219e5ab
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellInitTest.java
@@ -0,0 +1,134 @@
+/*
+ * 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.sysui.ShellController;
+import com.android.wm.shell.sysui.ShellInit;
+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 ShellInitTest extends ShellTestCase {
+
+    @Mock private ShellController mShellController;
+    @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 ShellInit mImpl;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mImpl = new ShellInit(mShellController, 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/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 00617b1..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
@@ -66,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;
@@ -85,7 +86,7 @@
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class DragAndDropPolicyTest {
+public class DragAndDropPolicyTest extends ShellTestCase {
 
     @Mock
     private Context mContext;
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/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
index c90a825..c7a261f 100644
--- 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
@@ -24,9 +24,13 @@
 
 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;
@@ -43,10 +47,12 @@
 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;
@@ -64,6 +70,7 @@
 @RunWith(AndroidJUnit4.class)
 public class SplitScreenControllerTests extends ShellTestCase {
 
+    @Mock ShellController mShellController;
     @Mock ShellTaskOrganizer mTaskOrganizer;
     @Mock SyncTransactionQueue mSyncQueue;
     @Mock RootTaskDisplayAreaOrganizer mRootTDAOrganizer;
@@ -81,21 +88,29 @@
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
-        mSplitScreenController = spy(new SplitScreenController(mTaskOrganizer, mSyncQueue, mContext,
-                mRootTDAOrganizer, mMainExecutor, mDisplayController, mDisplayImeController,
-                mDisplayInsetsController, mTransitions, mTransactionPool, mIconProvider,
-                mRecentTasks));
+        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);
-        mSplitScreenController.onFocusTaskChanged(focusTaskInfo);
+        doReturn(focusTaskInfo).when(mSplitScreenController).getFocusingTaskInfo();
         assertTrue(mSplitScreenController.isLaunchingAdjacently(
                 startIntent, SPLIT_POSITION_TOP_OR_LEFT));
 
@@ -103,7 +118,7 @@
         Intent diffIntent = createStartIntent("diffActivity");
         focusTaskInfo =
                 createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, diffIntent);
-        mSplitScreenController.onFocusTaskChanged(focusTaskInfo);
+        doReturn(focusTaskInfo).when(mSplitScreenController).getFocusingTaskInfo();
         assertFalse(mSplitScreenController.isLaunchingAdjacently(
                 startIntent, SPLIT_POSITION_TOP_OR_LEFT));
     }
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/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/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index 190e1cc..fba4249 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -142,6 +142,14 @@
         public int textEncoding;
     }
 
+    /** Callbacks for Emergency call events. */
+    public interface EmergencyCallCallback {
+        /** Callback invoked when an emergency call starts */
+        void onEmergencyCallStart(int subId);
+        /** Callback invoked when an emergency call ends */
+        void onEmergencyCallEnd();
+    }
+
     private class EmergencyCallListener extends TelephonyCallback implements
             TelephonyCallback.OutgoingEmergencyCallListener,
             TelephonyCallback.CallStateListener {
@@ -152,6 +160,7 @@
                 int subscriptionId) {
             mIsInEmergencyCall = true;
             if (DEBUG) Log.d(TAG, "onOutgoingEmergencyCall(): inEmergency = " + getInEmergency());
+            mEmergencyCallCallback.onEmergencyCallStart(subscriptionId);
         }
 
         @Override
@@ -163,6 +172,7 @@
                 if (mIsInEmergencyCall) {
                     mCallEndElapsedRealtimeMillis = SystemClock.elapsedRealtime();
                     mIsInEmergencyCall = false;
+                    mEmergencyCallCallback.onEmergencyCallEnd();
                 }
             }
         }
@@ -180,8 +190,11 @@
      */
     private Notification.Builder mNiNotificationBuilder;
 
+    private final EmergencyCallCallback mEmergencyCallCallback;
+
     public GpsNetInitiatedHandler(Context context,
                                   INetInitiatedListener netInitiatedListener,
+                                  EmergencyCallCallback emergencyCallCallback,
                                   boolean isSuplEsEnabled) {
         mContext = context;
 
@@ -190,6 +203,7 @@
         } else {
             mNetInitiatedListener = netInitiatedListener;
         }
+        mEmergencyCallCallback = emergencyCallCallback;
 
         setSuplEsEnabled(isSuplEsEnabled);
         mLocationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING
index a2b2ed5..e8c7ad2 100644
--- a/media/TEST_MAPPING
+++ b/media/TEST_MAPPING
@@ -4,6 +4,9 @@
       "name": "CtsMediaBetterTogetherTestCases"
     },
     {
+      "name": "mediaroutertest"
+    },
+    {
       "name": "CtsCameraTestCases",
       "options" : [
         {
@@ -25,11 +28,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/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/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/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/media/tests/MediaRouter/Android.bp b/media/tests/MediaRouter/Android.bp
index 2da6c98..4f9c6f1 100644
--- a/media/tests/MediaRouter/Android.bp
+++ b/media/tests/MediaRouter/Android.bp
@@ -25,7 +25,7 @@
         "testng",
         "truth-prebuilt",
     ],
-
+    test_suites: ["general-tests"],
     platform_apis: true,
     certificate: "platform",
 }
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..15b39d2 100644
--- a/packages/CompanionDeviceManager/res/values-am/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-am/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-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index d69ec1b..13dcb69 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/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-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml
index fcdd8cd..9df589a 100644
--- a/packages/CompanionDeviceManager/res/values-as/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-as/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-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..1644110 100644
--- a/packages/CompanionDeviceManager/res/values-be/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-be/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-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index 5e34bc7..101098c 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/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-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index 381d510..1eaf142 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/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-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..5cc72ae 100644
--- a/packages/CompanionDeviceManager/res/values-ca/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> per reproduir en continu aplicacions entre els dispositius"</string>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu <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>
     <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..0d44528 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"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>
     <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..51b9a89 100644
--- a/packages/CompanionDeviceManager/res/values-de/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-de/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
     <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..b7511ba 100644
--- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
     <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..bce46e8 100644
--- a/packages/CompanionDeviceManager/res/values-es/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
     <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..40a55b5 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nimel luba pääseda juurde telefoni fotodele, meediale ja märguannetele"</string>
     <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..28aaa87 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"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>
     <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..e52db88 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/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-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index bb4e9a5..67252c5 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteesi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) puolesta lupaa striimata sovelluksia laitteidesi välillä"</string>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteesi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) puolesta lupaa päästä puhelimesi kuviin, mediaan ja ilmoituksiin"</string>
     <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..b85099a 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
     <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..8a13866 100644
--- a/packages/CompanionDeviceManager/res/values-fr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
     <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..ccec06c 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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 contido de aplicacións entre os teus aparellos"</string>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
     <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..c6a8330 100644
--- a/packages/CompanionDeviceManager/res/values-gu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gu/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-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index a8c6c6f..867d70f 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/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-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..ac458b3 100644
--- a/packages/CompanionDeviceManager/res/values-hu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"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>
     <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..b4b29cb 100644
--- a/packages/CompanionDeviceManager/res/values-hy/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hy/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-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index 2ee559d..82fa00a 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
     <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..a2c628ff 100644
--- a/packages/CompanionDeviceManager/res/values-is/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-is/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
     <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..793f0b8 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
     <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..494c7eb 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,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-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml
index 7db3d0c..dbb1760 100644
--- a/packages/CompanionDeviceManager/res/values-ka/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ka/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-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml
index 58a625c..0d92a97b 100644
--- a/packages/CompanionDeviceManager/res/values-kk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kk/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-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index 7f3b933..4d85cfd 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/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,11 +35,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>
+    <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>
-    <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..a8a790a 100644
--- a/packages/CompanionDeviceManager/res/values-kn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kn/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="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"ನಿಮ್ಮ ಸಾಧನಗಳ ನಡುವೆ ಆ್ಯಪ್‌ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$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="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"ನಿಮ್ಮ ಫೋನ್‌ನ ಫೋಟೋಗಳು, ಮೀಡಿಯಾ ಮತ್ತು ಅಧಿಸೂಚನೆಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$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-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index 99acb18..2e4ef58 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/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-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index 63d6fba..bc140a2d3 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/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-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml
index 910a527..6a9197e 100644
--- a/packages/CompanionDeviceManager/res/values-lo/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lo/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-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml
index 5edd78d..f2cbfa0 100644
--- a/packages/CompanionDeviceManager/res/values-lt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"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>
     <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..e8947c7 100644
--- a/packages/CompanionDeviceManager/res/values-lv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
     <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..6769b6c 100644
--- a/packages/CompanionDeviceManager/res/values-mk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mk/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-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml
index be36c5c..07e6a43 100644
--- a/packages/CompanionDeviceManager/res/values-ml/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ml/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="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിനു വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു."</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"നിങ്ങളുടെ ഉപകരണങ്ങളിൽ ഒന്നിൽ നിന്ന് അടുത്തതിലേക്ക് ആപ്പുകൾ സ്ട്രീം ചെയ്യാൻ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിന് വേണ്ടി <xliff:g id="APP_NAME">%1$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="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിനു വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു."</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"നിങ്ങളുടെ ഫോണിലെ ഫോട്ടോകൾ, മീഡിയ, അറിയിപ്പുകൾ എന്നിവ ആക്സസ് ചെയ്യാൻ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിന് വേണ്ടി <xliff:g id="APP_NAME">%1$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-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..1cc0412 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/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-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml
index 70d0373..02743f0 100644
--- a/packages/CompanionDeviceManager/res/values-ms/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
     <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..6df06c1 100644
--- a/packages/CompanionDeviceManager/res/values-nb/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse til å strømme apper mellom enhetene dine, på vegne av <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">"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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse til å få tilgang til bilder, medier og varsler på telefonen din, på vegne av <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
     <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..fc22508 100644
--- a/packages/CompanionDeviceManager/res/values-ne/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ne/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-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..e567806 100644
--- a/packages/CompanionDeviceManager/res/values-or/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-or/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-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index 5fdcd36..dba72eb 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/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-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index c890fbc..360560a 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"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 treści z aplikacji na innym urządzeniu"</string>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"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>
     <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..f519239 100644
--- a/packages/CompanionDeviceManager/res/values-ru/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ru/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-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..14feef6f 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"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>
     <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..cefbff8 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
     <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..e2799b5 100644
--- a/packages/CompanionDeviceManager/res/values-sv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
     <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..9cb5f57 100644
--- a/packages/CompanionDeviceManager/res/values-sw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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 itiririshe programu kati ya vifaa vyako"</string>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<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 ifikie picha, maudhui na arifa za simu yako"</string>
     <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..fca9e0a 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/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="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> அனுமதி கோருகிறது"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"உங்கள் சாதனங்களுக்கு இடையே ஆப்ஸை ஸ்ட்ரீம் செய்ய உங்கள் <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$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="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> அனுமதி கோருகிறது"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"உங்கள் மொபைலில் உள்ள படங்கள், மீடியா, அறிவிப்புகள் ஆகியவற்றை அணுக உங்கள் <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$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-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml
index 96e7608..8a3df03 100644
--- a/packages/CompanionDeviceManager/res/values-te/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-te/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">"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>
+    <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,10 +35,10 @@
     <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>
+    <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..7c31a21 100644
--- a/packages/CompanionDeviceManager/res/values-th/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-th/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-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..756bcbb 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<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>
     <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..cc9f6b5 100644
--- a/packages/CompanionDeviceManager/res/values-uk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uk/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-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml
index ef93add..0740498 100644
--- a/packages/CompanionDeviceManager/res/values-ur/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ur/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">"‏اپنے فون سے اس معلومات تک رسائی حاصل Allow &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-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml
index 1813857..befb370 100644
--- a/packages/CompanionDeviceManager/res/values-uz/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"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>
     <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..7b3be44 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <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-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
index 6956aff..12dd892 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <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">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&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-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index 8d4623a..eef3009 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <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">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&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-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml
index c669736..ec87f2d 100644
--- a/packages/CompanionDeviceManager/res/values-zu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml
@@ -25,7 +25,7 @@
     <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>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"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>
     <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 +35,7 @@
     <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>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"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>
     <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-hi/strings.xml b/packages/PackageInstaller/res/values-hi/strings.xml
index 614fa90..c6a1f40 100644
--- a/packages/PackageInstaller/res/values-hi/strings.xml
+++ b/packages/PackageInstaller/res/values-hi/strings.xml
@@ -74,7 +74,7 @@
     <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"आपकी प्रोफ़ाइल के लिए यह ऐप्लिकेशन ज़रूरी है और उसे अनइंस्टॉल नहीं किया जा सकता."</string>
     <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"आपके डिवाइस एडमिन के लिए यह ऐप्लिकेशन ज़रूरी है और इसे अनइंस्टॉल नहीं किया जा सकता."</string>
     <string name="manage_device_administrators" msgid="3092696419363842816">"डिवाइस एडमिन ऐप्लिकेशन प्रबंधित करें"</string>
-    <string name="manage_users" msgid="1243995386982560813">"उपयोगकर्ताओं को प्रबंधित करें"</string>
+    <string name="manage_users" msgid="1243995386982560813">"उपयोगकर्ताओं को मैनेज करें"</string>
     <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> को अनइंस्‍टॉल नहीं किया जा सका."</string>
     <string name="Parse_error_dlg_text" msgid="1661404001063076789">"पैकेज को पार्स करने में कोई समस्‍या थी."</string>
     <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</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/res/values-te/strings.xml b/packages/PackageInstaller/res/values-te/strings.xml
index ebc43c4..c016bfc 100644
--- a/packages/PackageInstaller/res/values-te/strings.xml
+++ b/packages/PackageInstaller/res/values-te/strings.xml
@@ -59,7 +59,7 @@
     <string name="uninstall_application_text_current_user_work_profile" msgid="8788387739022366193">"మీ వర్క్ ప్రొఫైల్ నుండి ఈ యాప్‌ను మీరు అన్‌ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా?"</string>
     <string name="uninstall_update_text" msgid="863648314632448705">"ఈ యాప్‌ను ఫ్యాక్టరీ వెర్షన్‌తో భర్తీ చేయాలా? మొత్తం డేటా తీసివేయబడుతుంది."</string>
     <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"ఈ యాప్‌ను ఫ్యాక్టరీ వెర్షన్‌తో భర్తీ చేయాలా? మొత్తం డేటా తీసివేయబడుతుంది. దీని ప్రభావం కార్యాలయ ప్రొఫైళ్లు కలిగి ఉన్నవారితో సహా ఈ పరికర వినియోగదారులందరిపై ఉంటుంది."</string>
-    <string name="uninstall_keep_data" msgid="7002379587465487550">"<xliff:g id="SIZE">%1$s</xliff:g> యాప్ డేటాని ఉంచండి."</string>
+    <string name="uninstall_keep_data" msgid="7002379587465487550">"<xliff:g id="SIZE">%1$s</xliff:g> యాప్ డేటాను ఉంచండి."</string>
     <string name="uninstalling_notification_channel" msgid="840153394325714653">"అన్ఇన్‌స్టాల్ చేయబడుతున్నవి"</string>
     <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"విఫలమైన అన్‌ఇన్‌స్టాల్‌లు"</string>
     <string name="uninstalling" msgid="8709566347688966845">"అన్ఇన్‌స్టాల్ చేస్తోంది…"</string>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
index af05078..ac1a574f 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -19,6 +19,7 @@
 import static com.android.packageinstaller.PackageUtil.getMaxTargetSdkVersionForUid;
 
 import android.Manifest;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -28,12 +29,12 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ProviderInfo;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.RemoteException;
-import android.os.UserManager;
 import android.util.Log;
 
 import java.util.Arrays;
@@ -47,14 +48,12 @@
 
     private static final String DOWNLOADS_AUTHORITY = "downloads";
     private PackageManager mPackageManager;
-    private UserManager mUserManager;
     private boolean mAbortInstall = false;
 
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mPackageManager = getPackageManager();
-        mUserManager = getSystemService(UserManager.class);
         Intent intent = getIntent();
         String callingPackage = getCallingPackage();
         String callingAttributionTag = null;
@@ -119,8 +118,9 @@
         } else {
             Uri packageUri = intent.getData();
 
-            if (packageUri != null && packageUri.getScheme().equals(
-                    ContentResolver.SCHEME_CONTENT)) {
+            if (packageUri != null
+                    && packageUri.getScheme().equals(ContentResolver.SCHEME_CONTENT)
+                    && canPackageQuery(originatingUid, packageUri)) {
                 // [IMPORTANT] This path is deprecated, but should still work. Only necessary
                 // features should be added.
 
@@ -140,7 +140,14 @@
         }
 
         if (nextActivity != null) {
-            startActivity(nextActivity);
+            try {
+                startActivity(nextActivity);
+            } catch (SecurityException e) {
+                Intent result = new Intent();
+                result.putExtra(Intent.EXTRA_INSTALL_RESULT,
+                        PackageManager.INSTALL_FAILED_INVALID_URI);
+                setResult(RESULT_FIRST_USER, result);
+            }
         }
         finish();
     }
@@ -229,4 +236,21 @@
         final ApplicationInfo appInfo = downloadProviderPackage.applicationInfo;
         return (appInfo.isSystemApp() && uid == appInfo.uid);
     }
+
+    @NonNull
+    private boolean canPackageQuery(int originatingUid, Uri packageUri) {
+        String callingPackage = mPackageManager.getPackagesForUid(originatingUid)[0];
+        ProviderInfo info = mPackageManager.resolveContentProvider(packageUri.getAuthority(),
+                PackageManager.ComponentInfoFlags.of(0));
+        if (info == null) {
+            return false;
+        }
+        String targetPackage = info.packageName;
+
+        try {
+            return mPackageManager.canPackageQuery(callingPackage, targetPackage);
+        } catch (NameNotFoundException e) {
+            return false;
+        }
+    }
 }
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/PrintSpooler/res/values-te/strings.xml b/packages/PrintSpooler/res/values-te/strings.xml
index 62cfcc4..500a472 100644
--- a/packages/PrintSpooler/res/values-te/strings.xml
+++ b/packages/PrintSpooler/res/values-te/strings.xml
@@ -43,7 +43,7 @@
     <string name="summary_template" msgid="8899734908625669193">"సారాంశం, కాపీలు <xliff:g id="COPIES">%1$s</xliff:g>, కాగితం పరిమాణం <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
     <string name="expand_handle" msgid="7282974448109280522">"విస్తరణ హ్యాండిల్"</string>
     <string name="collapse_handle" msgid="6886637989442507451">"కుదింపు హ్యాండిల్"</string>
-    <string name="print_button" msgid="645164566271246268">"ముద్రించు"</string>
+    <string name="print_button" msgid="645164566271246268">"ప్రింట్ చేయండి"</string>
     <string name="savetopdf_button" msgid="2976186791686924743">"PDF లాగా సేవ్ చేయి"</string>
     <string name="print_options_expanded" msgid="6944679157471691859">"ముద్రణ ఎంపికలు విస్తరించబడ్డాయి"</string>
     <string name="print_options_collapsed" msgid="7455930445670414332">"ముద్రణ ఎంపికలు కుదించబడ్డాయి"</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/CollapsingToolbarBaseActivity/Android.bp b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
index 238e65e..7968e96 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
@@ -25,6 +25,7 @@
     min_sdk_version: "29",
     apex_available: [
         "//apex_available:platform",
+        "com.android.adservices",
         "com.android.cellbroadcast",
         "com.android.permission",
     ],
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/MainSwitchPreference/Android.bp b/packages/SettingsLib/MainSwitchPreference/Android.bp
index fc06fdc..dd29827 100644
--- a/packages/SettingsLib/MainSwitchPreference/Android.bp
+++ b/packages/SettingsLib/MainSwitchPreference/Android.bp
@@ -23,6 +23,7 @@
     min_sdk_version: "28",
     apex_available: [
         "//apex_available:platform",
+        "com.android.adservices",
         "com.android.cellbroadcast",
     ],
 }
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
index 32260a4..ca84db8 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
@@ -19,6 +19,11 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="wrap_content"
     android:layout_width="match_parent"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingTop="@dimen/settingslib_switchbar_margin"
+    android:paddingBottom="@dimen/settingslib_switchbar_margin"
     android:orientation="vertical">
 
     <LinearLayout
@@ -26,7 +31,6 @@
         android:minHeight="@dimen/settingslib_min_switch_bar_height"
         android:layout_height="wrap_content"
         android:layout_width="match_parent"
-        android:layout_margin="@dimen/settingslib_switchbar_margin"
         android:paddingStart="@dimen/settingslib_switchbar_padding_left"
         android:paddingEnd="@dimen/settingslib_switchbar_padding_right">
 
diff --git a/packages/SettingsLib/SettingsTransition/Android.bp b/packages/SettingsLib/SettingsTransition/Android.bp
index f06a9a7..708141b 100644
--- a/packages/SettingsLib/SettingsTransition/Android.bp
+++ b/packages/SettingsLib/SettingsTransition/Android.bp
@@ -20,6 +20,7 @@
     min_sdk_version: "29",
     apex_available: [
         "//apex_available:platform",
+        "com.android.adservices",
         "com.android.cellbroadcast",
         "com.android.permission",
     ],
diff --git a/packages/SettingsLib/Utils/Android.bp b/packages/SettingsLib/Utils/Android.bp
index 7d5eb69..1b00261 100644
--- a/packages/SettingsLib/Utils/Android.bp
+++ b/packages/SettingsLib/Utils/Android.bp
@@ -23,6 +23,7 @@
     apex_available: [
 
         "//apex_available:platform",
+        "com.android.adservices",
         "com.android.permission",
         "com.android.cellbroadcast",
     ],
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-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index e933aab..264faad 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Lêeroordrag"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Invoertoestel"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internettoegang"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontakdeling"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Gebruik vir kontakdeling"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Deling van internetverbinding"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Teksboodskappe"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM-toegang"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 1ccc1b3..b68cbd7 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ፋይል ማስተላለፍ"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ግቤት መሣሪያ"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"የበይነመረብ ድረስ"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"እውቂያ ማጋራት"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"እውቂያን ለማጋራት ተጠቀም"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"የበይነ መረብ ተያያዥ ማጋሪያ"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"የጽሑፍ መልዕክቶች"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"የሲም መዳረሻ"</string>
@@ -667,7 +669,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-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index cf6040e..c8b263b 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"نقل الملف"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"جهاز الإرسال"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"استخدام الإنترنت"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"مشاركة جهات الاتصال"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"استخدام مع مشاركة جهة الاتصال"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"مشاركة اتصال الإنترنت"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"الرسائل النصية"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"‏الوصول إلى شريحة SIM"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 222b6ca..ea1aff0 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ফাইল স্থানান্তৰণ"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ইনপুট ডিভাইচ"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ইণ্টাৰনেট সংযোগ"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"সম্পৰ্ক শ্বেয়াৰ কৰা"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"সম্পৰ্ক শ্বেয়াৰ কৰিবলৈ ব্যৱহাৰ কৰক"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ইণ্টাৰনেট সংযোগ শ্বেয়াৰ"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"পাঠ বাৰ্তা"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"ছিম প্ৰৱেশ"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 4efc63c..88333e82 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Fayl transferi"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Daxiletmə cihazı"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"İnternetə giriş"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontakt paylaşımı"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Kontakt paylaşımı üçün istifadə edin"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"internet bağlantı paylaşımı"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Mətn Mesajları"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM-karta giriş"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 2a19d64..a84d019 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenos datoteke"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ulazni uređaj"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Pristup Internetu"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Deljenje kontakata"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Koristite za deljenje kontakata"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Deljenje internet veze"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS-ovi"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Pristup SIM kartici"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 1892ec9..37f8410 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Перадача файлаў"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Прылада ўводу"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Доступ у інтэрнэт"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Абагульванне кантактаў"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Выкарыстоўваць для абагульвання кантактаў"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Прадастаўленне доступу да Інтэрнэту"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Тэкставыя паведамленні"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Доступ да SIM-карты"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index a309c8e..f2cf69e 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Прехвърляне на файл"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Входно устройство"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Достъп до интернет"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Споделяне на контакти"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Използване за споделяне на контакти"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Споделяне на връзката с интернет"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Текстови съобщения"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Достъп до SIM картата"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index a99a90c..801fb34 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ফাইল স্থানান্তর"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ইনপুট ডিভাইস"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ইন্টারনেট অ্যাক্সেস"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"পরিচিতি শেয়ার করা"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"পরিচিতি শেয়ার করার কাজে ব্যবহার করুন"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ইন্টারনেট কানেকশন শেয়ার করা হচ্ছে"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"এসএমএস"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"সিম অ্যাক্সেস"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index db3220a..61082f6 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenošenje fajla"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ulazni uređaj"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Pristup internetu"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Dijeljenje kontakata"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Koristi za dijeljenje kontakta"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Dijeljenje internet veze"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS-ovi"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Pristup SIM-u"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 4fe6187..881f9d4 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferència de fitxers"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositiu d\'entrada"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Accés a Internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Compartició de contactes"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"S\'utilitza per compartir contactes."</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Compartició de connexió d\'Internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Missatges de text"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Accés a la SIM"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 872e38e..7f314bd 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Přenos souborů"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Vstupní zařízení"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Přístup k internetu"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Sdílení kontaktů"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Použít ke sdílení kontaktů"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Sdílení internetového připojení"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Textové zprávy"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Přístup k SIM kartě"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index bb7bee2..c470b81 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Filoverførsel"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Inputenhed"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetadgang"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Deling af kontakter"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Brug til deling af kontakter"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Deling af internetforbindelse"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Sms-beskeder"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Adgang til SIM-kort"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index a1693ce..34a622b 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Dateiübertragung"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Eingabegerät"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetzugriff"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktfreigabe"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Für Kontaktfreigabe nutzen"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Freigabe der Internetverbindung"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Zugriff auf SIM"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index d775dd7..fdc7419 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Μεταφορά αρχείου"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Συσκευή εισόδου"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Πρόσβαση στο Διαδίκτυο"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Κοινή χρήση επαφών"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Για κοινή χρήση επαφών"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Κοινή χρήση σύνδεσης στο Διαδίκτυο"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Μηνύματα κειμένου"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Πρόσβαση SIM"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 8cad471..234109b 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"File transfer"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Input device"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internet access"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Contact sharing"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Use for contact sharing"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internet connection sharing"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Text messages"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM access"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 2614f71..d88bb0e 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"File transfer"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Input device"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internet access"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Contact sharing"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Use for contact sharing"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internet connection sharing"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Text messages"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM access"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 8cad471..234109b 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"File transfer"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Input device"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internet access"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Contact sharing"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Use for contact sharing"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internet connection sharing"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Text messages"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM access"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 8cad471..234109b 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"File transfer"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Input device"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internet access"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Contact sharing"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Use for contact sharing"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internet connection sharing"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Text messages"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM access"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index c956bd4..5d775d3 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -117,8 +117,8 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‎‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‎‎File transfer‎‏‎‎‏‎"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‎‎‏‎‎‏‎‎‏‎‏‎‎‏‏‎‏‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎Input device‎‏‎‎‏‎"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎Internet access‎‏‎‎‏‎"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‏‎Contact sharing‎‏‎‎‏‎"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‎‏‎‎‏‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎Use for contact sharing‎‏‎‎‏‎"</string>
+    <string name="bluetooth_profile_pbap" msgid="4262303387989406171">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‏‎‏‏‏‎‎‎‏‏‏‎‏‏‎‏‏‎Contacts and call history sharing‎‏‎‎‏‎"</string>
+    <string name="bluetooth_profile_pbap_summary" msgid="6466456791354759132">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎‏‎‏‏‏‏‏‎‏‏‏‎‎‎Use for contacts and call history sharing‎‏‎‎‏‎"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‎Internet connection sharing‎‏‎‎‏‎"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‏‏‏‎Text Messages‎‏‎‎‏‎"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎SIM Access‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index f7783a4..98c1400 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferencia de archivos"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acceso a Internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Compartir contactos"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Utilizar para compartir contactos"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Compartir conexión a Internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Mensajes de texto"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Acceso a SIM"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 1116134..90c4fb8 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferencia de archivos"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acceso a Internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Compartir contactos"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Usar para compartir contactos"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Compartir conexión a Internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Mensajes de texto"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Acceso a tarjeta SIM"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 64b5249..a6c787a 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Failiedastus"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Sisendseade"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Juurdepääs internetile"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktide jagamine"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Kasutamine kontaktide jagamiseks"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Interneti-ühenduse jagamine"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Tekstsõnumid"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Juurdepääs SIM-ile"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 1cfec2c..87cfaa8 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Fitxategi-transferentzia"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Sarrerako gailua"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Interneteko konexioa"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktuak partekatzea"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Erabili kontaktuak partekatzeko"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Interneteko konexioa partekatzea"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Testu-mezuak"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIMerako sarbidea"</string>
@@ -389,7 +391,7 @@
     <string name="enable_gpu_debug_layers" msgid="4986675516188740397">"Gaitu GPUaren arazketa-geruzak"</string>
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Eman GPUaren arazketa-geruzak kargatzeko baimena arazketa-aplikazioei"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Gaitu saltzaileen erregistro xehatuak"</string>
-    <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sartu gailuaren berariazko saltzaileen erregistro gehigarriak akatsen txostenetan; baliteke haiek informazio pribatua izatea, bateria gehiago erabiltzea edo biltegiratzeko toki gehiago hartzea."</string>
+    <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sartu gailuaren berariazko saltzaileen erregistro gehigarriak akatsen txostenetan; baliteke haiek informazio pribatua izatea, bateria gehiago erabiltzea eta/edo biltegiratzeko toki gehiago hartzea."</string>
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Leihoen animazio-eskala"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Trantsizioen animazio-eskala"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatzailearen iraupen-eskala"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 8e702db..51d74dd 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"انتقال فایل"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"دستگاه ورودی"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"دسترسی به اینترنت"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"هم‌رسانی مخاطب"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"استفاده برای هم‌رسانی مخاطب"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"اشتراک‌گذاری اتصال اینترنت"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"پیام‌های نوشتاری"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"دسترسی سیم‌کارت"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 7186248..c0f90b8 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Tiedostonsiirto"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Syöttölaite"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetyhteys"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Yhteystietojen jakaminen"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Käytä yhteystietojen jakamiseen"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internetyhteyden jakaminen"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Tekstiviestit"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM-kortin käyttö"</string>
@@ -665,7 +667,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-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 6b5102c..14515cd 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transfert de fichier"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Périphérique d\'entrée"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Accès Internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Partage de contacts"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Utiliser pour le partage de contacts"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Partage de connexion Internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Messages texte"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Accès à la carte SIM"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 4702662..19ea6dd 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transfert de fichiers"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Périphérique d\'entrée"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Accès Internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Partage de contacts"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Utiliser pour le partage de contacts"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Partage de connexion Internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Accès à la carte SIM"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index ec63661..94fa72a 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferencia de ficheiros"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acceso a Internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Compartir contactos"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Utilizar para compartir contactos"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Uso compartido da conexión a Internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Mensaxes de texto"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Acceso á SIM"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index af54656..a474d82 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ફાઇલ સ્થાનાંતરણ"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ઇનપુટ ડિવાઇસ"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ઇન્ટરનેટ ઍક્સેસ"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"સંપર્ક શેરિંગ"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"સંપર્ક શેરિંગ માટે ઉપયોગ કરો"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ઇન્ટરનેટ કનેક્શન શેરિંગ"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"ટેક્સ્ટ સંદેશા"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"સિમ ઍક્સેસ"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 96fba8f..55fc547 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"फ़ाइल स्थानांतरण"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"इनपुट डिवाइस"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"इंटरनेट ऐक्सेस"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"संपर्क शेयर करना"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"संपर्क साझाकरण के लिए उपयोग करें"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"इंटरनेट कनेक्शन साझाकरण"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"लेख संदेश"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"सिम ऐक्सेस"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index c9be92e..55a3e5e 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prijenos datoteke"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ulazni uređaj"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Pristup internetu"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Dijeljenje kontakata"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Upotrijebi za dijeljenje kontakata"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Dijeljenje internetske veze"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS-ovi"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Pristup SIM-u"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 232a963..2454d1c 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Fájlátvitel"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Beviteli eszköz"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetelérés"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Névjegyek megosztása"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Használja a névjegyek megosztására"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internetkapcsolat megosztása"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Szöveges üzenetek"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM-elérés"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 94c4abd..8966551 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Ֆայլերի փոխանցում"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ներմուծման սարք"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Ինտերնետի հասանելիություն"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Կոնտակտների փոխանակում"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Օգտագործել կոնտակտի համօգտագործման համար"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Ինտերնետ կապի տարածում"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS հաղորդագրություններ"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM քարտի հասանելիություն"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index cd74fea..c525317 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transfer file"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Perangkat masukan"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Akses Internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Berbagi kontak"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Gunakan untuk berbagi kontak"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Berbagi koneksi internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Akses SIM"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index d5b4380..c06d2f0 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Skráaflutningur"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Inntakstæki"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetaðgangur"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Deiling tengiliða"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Nota til að deila tengiliðum"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Deiling nettengingar"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Textaskilaboð"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Aðgangur að SIM-korti"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 7130c80..b3ac25a 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Trasferimento file"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo di input"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Accesso a Internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Condivisione contatti"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Usa per condivisione contatti"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Condivisione connessione Internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Accesso alla SIM"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 3e7b7d8..f021b37 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"העברת קבצים"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"מכשיר קלט"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"גישה לאינטרנט"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"שיתוף אנשי קשר"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"שימוש עבור שיתוף אנשי קשר"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"שיתוף חיבור לאינטרנט"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"הודעות טקסט"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"‏גישה ל-SIM"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index abbb760..2994e4d 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ファイル転送"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"入力デバイス"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"インターネットアクセス"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"連絡先の共有"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"連絡先の共有に使用"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"インターネット接続の共有"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"テキスト メッセージ"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIMアクセス"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 87222c2..0c3277b 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ფაილების გადაცემა"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"შეყვანის მოწყობილობა"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ინტერნეტზე წვდომა"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"კონტაქტის გაზიარება"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"კონტაქტის გაზიარებისთვის გამოყენება"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ინტერნეტ კავშირის გაზიარება"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"ტექსტური შეტყობინებები"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM წვდომა"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 4e6c576..63c9575 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Файл жіберу"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Кіріс құрылғысы"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Интернетке қосылу"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Контакт бөлісу"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Контактіні бөлісу үшін пайдалану"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Интернет байланысын ортақ қолдану"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Мәтіндік хабарлар"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM картасына кіру"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 71c0f20..9b9228a 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ផ្ទេរ​ឯកសារ"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ឧបករណ៍​បញ្ចូល"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ការចូលប្រើ​អ៊ីនធឺណិត"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"ការ​ចែករំលែក​​ទំនាក់ទំនង"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"ប្រើ​សម្រាប់​ការ​ចែករំលែក​ទំនាក់ទំនង"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ចែករំលែក​ការ​តភ្ជាប់​អ៊ីនធឺណិត"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"សារ​ជាអក្សរ"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"ការចូលដំណើរការស៊ីម"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 2dacee0..7071598 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ಫೈಲ್ ವರ್ಗಾವಣೆ"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ಇನ್‌ಪುಟ್‌ ಸಾಧನ"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶ"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"ಸಂಪರ್ಕ ಹಂಚಿಕೆ"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"ಸಂಪರ್ಕ ಹಂಚಿಕೆಗಾಗಿ ಬಳಸಿ"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕ ಹಂಚಿಕೊಳ್ಳುವಿಕೆ"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"ಪಠ್ಯ ಸಂದೇಶಗಳು"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"ಸಿಮ್ ಪ್ರವೇಶ"</string>
@@ -232,7 +234,7 @@
     <string name="vpn_settings_not_available" msgid="2894137119965668920">"VPN ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಈ ಬಳಕೆದಾರರಿಗೆ ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="tethering_settings_not_available" msgid="266821736434699780">"ಟೆಥರಿಂಗ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಈ ಬಳಕೆದಾರರಿಗೆ ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="apn_settings_not_available" msgid="1147111671403342300">"ಪ್ರವೇಶ ಬಿಂದು ಹೆಸರಿನ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಈ ಬಳಕೆದಾರರಿಗೆ ಲಭ್ಯವಿಲ್ಲ"</string>
-    <string name="enable_adb" msgid="8072776357237289039">"USB ಡೀಬಗಿಂಗ್‌"</string>
+    <string name="enable_adb" msgid="8072776357237289039">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ"</string>
     <string name="enable_adb_summary" msgid="3711526030096574316">"USB ಸಂಪರ್ಕಗೊಂಡಾಗ ಡೀಬಗ್ ಮೋಡ್"</string>
     <string name="clear_adb_keys" msgid="3010148733140369917">"USB ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯ ಅಧಿಕೃತಗೊಳಿಸುವಿಕೆಗಳನ್ನು ಹಿಂತೆಗೆದುಕೊಳ್ಳಿ"</string>
     <string name="enable_adb_wireless" msgid="6973226350963971018">"ವೈರ್‌ಲೆಸ್ ಡೀಬಗಿಂಗ್"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 899f2de..6ba289d 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"파일 전송"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"입력 장치"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"인터넷 액세스"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"연락처 공유"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"연락처 공유용"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"인터넷 연결 공유"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"문자 메시지"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM 액세스"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 5b9485a..3eb43fa 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Файл алмашуу"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Киргизүү түзмөгү"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Интернетке мүмкүнчүлүк алуу"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Байланышты бөлүшүү"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Байланышты бөлүшүү үчүн колдонуу"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Интернет байланышын бөлүшүү"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS билдирүүлөрү"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM картаны пайдалануу мүмкүнчүлүгү"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index a65ada0..2dcad1f 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ການໂອນຍ້າຍໄຟລ໌"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ອຸປະກອນປ້ອນຂໍ້ມູນ"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ການເຂົ້າເຖິງອິນເຕີເນັດ"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"ການ​ແບ່ງ​ປັນ​ລາຍ​ຊື່​ຜູ້​ຕິດ​ຕໍ່"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"​ໃຊ້​ສຳ​ລັບການ​ແບ່ງ​ປັນ​ລາຍ​ຊື່​ຜູ່​ຕິດ​ຕໍ່"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ການແບ່ງປັນການເຊື່ອມຕໍ່ອິນເຕີເນັດ"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"ຂໍ້ຄວາມ"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"ການ​ເຂົ້າ​ເຖິງ SIM"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 7985678..8aaec47 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Failo perkėlimas"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Įvesties įrenginys"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Prieiga prie interneto"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktų bendrinimas"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Naudoti kontaktams bendrinti"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Interneto ryšio bendrinimas"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Teksto pranešimai"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM prieiga"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 63af239..fcfb9b89 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Failu pārsūtīšana"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ievades ierīce"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Interneta piekļuve"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktpersonas informācijas kopīgošana"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Izmantot kontaktpersonas informācijas kopīgošanai"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Interneta savienojuma koplietošana"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Īsziņas"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Piekļuve SIM kartei"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 46458cd..144de00 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Пренос на датотека"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Влезен уред"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Пристап до интернет"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Споделување контакти"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Користи за споделување контакти"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Споделување конекција на интернет"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Текстуални пораки"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Пристап до SIM"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 0d093bd..59cd6bc 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ഫയൽ കൈമാറൽ"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ഇൻപുട്ട് ഉപകരണം"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ഇന്‍റർനെറ്റ് ആക്‌സസ്"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"കോൺടാക്‌റ്റ് പങ്കിടൽ"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"കോൺടാക്‌റ്റ് പങ്കിടലിനായി ഉപയോഗിക്കുക"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ഇന്റർനെറ്റ് കണക്ഷൻ പങ്കിടൽ"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"അക്ഷര സന്ദേശങ്ങൾ"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"സിം ആക്സസ്"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 75abf99..1bd6bea 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Файл дамжуулалт"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Оруулах төхөөрөмж"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Интернэт хандалт"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Харилцагч хуваалцах"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Харилцагч хуваалцахад ашиглах"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Интернэт холболтыг хуваалцах"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Мессеж"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM Хандалт"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 42832f1..c163219 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"फाइल स्थानांतरण"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"इनपुट डिव्हाइस"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"इंटरनेट अ‍ॅक्सेस"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"संपर्क शेअरिंग"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"संपर्क सामायिकरणासाठी वापरा"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"इंटरनेट कनेक्शन शेअररण"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"मजकूर मेसेज"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"सिम अ‍ॅक्सेस"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 41fdec6..55c8814 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Pemindahan fail"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Peranti input"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Akses Internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Perkongsian kenalan"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Gunakan untuk perkongsian kenalan"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Perkongsian sambungan Internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Mesej Teks"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Akses SIM"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 3c7e5b3..38b1fe8 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ဖိုင်လွဲပြောင်းခြင်း"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ထည့်သွင်းသော စက်"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"အင်တာနက်ချိတ်ဆက်ခြင်း"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"အဆက်အသွယ်ကို မျှဝေခြင်း"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"အဆက်အသွယ်ကို မျှဝေရန် အတွက် သုံးရန်"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"အင်တာနက်ဆက်သွယ်မှု မျှဝေခြင်း"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"မိုဘိုင်းမက်ဆေ့ဂျ်များ"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM အသုံးပြုခြင်း"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 838e961..ef2111d 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Filoverføring"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Inndataenhet"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internett-tilgang"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktdeling"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Bruk til kontaktdeling"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Deling av internettilkobling"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Tekstmeldinger"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Tilgang til SIM-kortet"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index d3678d3..9fa7749 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"फाइल स्थानान्तरण"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"इनपुट उपकरण"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"इन्टरनेट पहुँच"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"कन्ट्याक्ट सेयरिङ"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"सम्पर्क साझेदारीका लागि प्रयोग"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"इन्टरनेट जडान साझेदारी गर्दै"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"टेक्स्ट म्यासेजहरू"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM पहुँच"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index b0a5afd..f4cbfd5 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Bestandsoverdracht"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Invoerapparaat"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internettoegang"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Contacten delen"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Gebruiken voor contacten delen"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internetverbinding delen"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Sms-berichten"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Sim-toegang"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index f2aa3b6..76c3671 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ଫାଇଲ୍‌ ଟ୍ରାନ୍ସଫର୍‌"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ଇନ୍‌ପୁଟ୍‌ ଡିଭାଇସ୍"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ଇଣ୍ଟର୍‌ନେଟ୍‌ ଆକ୍ସେସ୍"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"ଯୋଗାଯୋଗ ସେୟାରିଂ"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"ଯୋଗାଯୋଗ ସେୟାର୍‌ କରିବା ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ଇଣ୍ଟର୍‌ନେଟ୍‌ ସଂଯୋଗ ଶେୟାରିଙ୍ଗ"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"ଟେକ୍ସଟ୍ ମେସେଜ୍"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM ଆକ୍ସେସ୍‌"</string>
@@ -148,7 +150,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 +307,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 +526,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 +626,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-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 1330fa7..e34ece8 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ਇਨਪੁੱਟ ਡੀਵਾਈਸ"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"ਸੰਪਰਕ ਸਾਂਝਾਕਰਨ"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"ਸੰਪਰਕ ਸ਼ੇਅਰਿੰਗ ਲਈ ਵਰਤੋ"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ਇੰਟਰਨੈੱਟ ਕਨੈਕਸ਼ਨ ਸਾਂਝਾਕਰਨ"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"ਲਿਖਤ ਸੁਨੇਹੇ"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"ਸਿਮ ਪਹੁੰਚ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index d700e55..fe56c61 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Przesyłanie pliku"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Urządzenie wejściowe"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Dostęp do internetu"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Udostępnianie kontaktów"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Używaj do udostępniania kontaktów"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Udostępnianie połączenia internetowego"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS-y"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Dostęp do karty SIM"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 2ae177d..aa66c6043 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferência de arquivo"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acesso à Internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Compartilhar contatos"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Usar para compartilhar contatos"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Compartilhamento de conexão à Internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Mensagens de texto"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Acesso ao chip"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 8d9a619..cf76780 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferência do ficheiro"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acesso à internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Partilha de contactos"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Utilizar para a partilha de contactos"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Partilha da ligação à internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Mensagens de texto"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Acesso ao SIM"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 2ae177d..aa66c6043 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferência de arquivo"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acesso à Internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Compartilhar contatos"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Usar para compartilhar contatos"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Compartilhamento de conexão à Internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Mensagens de texto"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Acesso ao chip"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 20b39a5..946f4b7 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transfer de fișiere"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispozitiv de intrare"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acces la internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Acces la Agendă"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Utilizați pentru a permite accesul la Agendă"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Distribuirea conexiunii la internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Mesaje text"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Acces la SIM"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index aa467ace..bcd83cf 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Профиль OPP"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Профиль HID"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Доступ к интернету"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Обмен контактами"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Использовать для обмена контактами"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Профиль PAN"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Текстовые сообщения"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Доступ к SIM-карте"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 748a93f..7f5eb49 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ගොනු හුවමාරුව"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ආදාන උපාංගය"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"අන්තර්ජාල ප්‍රවේශය"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"සම්බන්ධතා බෙදාගැනීම"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"සම්බන්ධතා බෙදාගැනීම සඳහා භාවිතා කිරීම"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"අන්තර්ජාල සම්බන්ධතා බෙදාගැනීම"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"පෙළ පණිවිඩ"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM ප්‍රවේශය"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 3845951..31925ea 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenos súborov"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Vstupné zariadenie"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Prístup na internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Zdieľanie kontaktov"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Použiť na zdieľanie kontaktov"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Zdieľanie pripojenia na Internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Textové správy"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Prístup k SIM karte"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 1d87352..687ff38 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenos datoteke"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Vnosna naprava"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetni dostop"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Deljenje stikov"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Uporabi za deljenje stikov"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Deljenje internetne povezave"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Sporočila SMS"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Dostop do kartice SIM"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 647c2e1..7e96990 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferimi i skedarëve"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Pajisja e hyrjes"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Qasje në internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Ndarja e kontakteve"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Përdore për ndarjen e kontakteve"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Ndarja e lidhjes së internetit"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Mesazhet me tekst"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Qasje në kartën SIM"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 6ff020c..2842223 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Пренос датотеке"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Улазни уређај"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Приступ Интернету"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Дељење контаката"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Користите за дељење контаката"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Дељење интернет везе"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS-ови"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Приступ SIM картици"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index ea284d5..b0f8df5 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Filöverföring"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Indataenhet"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetåtkomst"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktdelning"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Använd för kontaktdelning"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Delning av Internetanslutning"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Sms"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM-åtkomst"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 50ca8d9..7e62d3f 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Uhamishaji wa faili"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Kifaa cha kuingiza"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Ufikiaji wa intaneti"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kushiriki anwani"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Tumia kwa kushiriki anwani"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Kushiriki muunganisho wa tovuti"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Ufikiaji wa SIM"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 5b8ae38..abab3fb 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ஃபைல் இடமாற்றம்"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"உள்ளீட்டுச் சாதனம்"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"இணைய அணுகல்"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"தொடர்பைப் பகிர்தல்"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"தொடர்புப் பகிர்தலுக்குப் பயன்படுத்து"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"இணைய இணைப்பு பகிர்தல்"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"உரைச் செய்திகள்"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"சிம் அணுகல்"</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..a362f24 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ఫైల్ బదిలీ"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ఇన్‌పుట్ పరికరం"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ఇంటర్నెట్ యాక్సెస్"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"కాంటాక్ట్ షేరింగ్"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"కాంటాక్ట్ షేరింగ్ కోసం ఉపయోగించండి"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ఇంటర్నెట్ కనెక్షన్ షేరింగ్"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"టెక్స్ట్ మెసేజ్‌లు"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM యాక్సెస్"</string>
@@ -204,7 +206,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>
@@ -270,7 +272,7 @@
     <string name="bt_hci_snoop_log" msgid="7291287955649081448">"బ్లూటూత్ HCI రహస్య లాగ్‌ను ఎనేబుల్ చేయి"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"బ్లూటూత్‌ ప్యాకెట్‌లను క్యాప్చర్ చేయి. (ఈ సెట్టింగ్‌ని మార్చిన తర్వాత బ్లూటూత్‌ని టోగుల్ చేయండి)"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"OEM అన్‌లాకింగ్"</string>
-    <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"బూట్‌లోడర్ అన్‌లాక్ కావడానికి అనుమతించు"</string>
+    <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"బూట్‌లోడర్ అన్‌లాక్ కావడానికి అనుమతించండి"</string>
     <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"OEM అన్‌లాకింగ్‌ను అనుమతించాలా?"</string>
     <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"హెచ్చరిక: ఈ సెట్టింగ్ ఆన్ చేయబడినప్పుడు పరికరం రక్షణ లక్షణాలు ఈ పరికరంలో పని చేయవు."</string>
     <string name="mock_location_app" msgid="6269380172542248304">"డమ్మీ లొకేష‌న్‌ యాప్‌ను ఎంచుకోండి"</string>
@@ -281,7 +283,7 @@
     <string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi‑Fi విశదీకృత లాగింగ్‌ను ప్రారంభించండి"</string>
     <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi స్కాన్ కుదింపు"</string>
     <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Wi‑Fi నిరంతరం కాని MAC ర్యాండమైజేషన్"</string>
-    <string name="mobile_data_always_on" msgid="8275958101875563572">"మొబైల్ డేటాని ఎల్లప్పుడూ యాక్టివ్‌గా ఉంచు"</string>
+    <string name="mobile_data_always_on" msgid="8275958101875563572">"మొబైల్ డేటాను ఎల్లప్పుడూ యాక్టివ్‌గా ఉంచు"</string>
     <string name="tethering_hardware_offload" msgid="4116053719006939161">"టెథెరింగ్ హార్డ్‌వేర్ యాగ్జిలరేషన్"</string>
     <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"పేర్లు లేని బ్లూటూత్ పరికరాలు  చూపించు"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"సంపూర్ణ వాల్యూమ్‌‍ను డిజేబుల్ చేయి"</string>
@@ -336,7 +338,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>
@@ -381,7 +383,7 @@
     <string name="debug_layout_summary" msgid="8825829038287321978">"క్లిప్ సరిహద్దులు, అంచులు మొ. చూపు"</string>
     <string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL లేఅవుట్ దిశను నిర్బంధం చేయండి"</string>
     <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"అన్ని లొకేల్‌ల కోసం RTLకి స్క్రీన్ లేఅవుట్ దిశను నిర్భందించు"</string>
-    <string name="window_blurs" msgid="6831008984828425106">"విండో-స్థాయి బ్లర్ అనుమతించు"</string>
+    <string name="window_blurs" msgid="6831008984828425106">"విండో-స్థాయి బ్లర్ అనుమతించండి"</string>
     <string name="force_msaa" msgid="4081288296137775550">"4x MSAA అమలు తప్పనిసరి"</string>
     <string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 యాప్‌లలో 4x MSAAను ప్రారంభించండి"</string>
     <string name="show_non_rect_clip" msgid="7499758654867881817">"దీర్ఘ చతురస్రం కాని క్లిప్ చర్యలను డీబగ్ చేయండి"</string>
@@ -402,7 +404,7 @@
     <string name="show_all_anrs_summary" msgid="8562788834431971392">"బ్యాక్‌గ్రౌండ్ యాప్‌ల కోసం యాప్ ప్రతిస్పందించడం లేదు అనే డైలాగ్‌ను చూపు"</string>
     <string name="show_notification_channel_warnings" msgid="3448282400127597331">"ఛానెల్ హెచ్చరికల నోటిఫికేషన్‌‌ను చూపు"</string>
     <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"చెల్లుబాటు అయ్యే ఛానెల్ లేకుండా యాప్ నోటిఫికేషన్‌ను పోస్ట్ చేస్తున్నప్పుడు స్క్రీన్‌పై హెచ్చరికను చూపిస్తుంది"</string>
-    <string name="force_allow_on_external" msgid="9187902444231637880">"యాప్‌లను బాహ్య స్టోరేజ్‌లో తప్పనిసరిగా అనుమతించు"</string>
+    <string name="force_allow_on_external" msgid="9187902444231637880">"యాప్‌లను బాహ్య స్టోరేజ్‌లో తప్పనిసరిగా అనుమతించండి"</string>
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"ఏ యాప్‌ను అయినా మానిఫెస్ట్ విలువలతో సంబంధం లేకుండా బాహ్య స్టోరేజ్‌లో సేవ్ చేయడానికి అనుమతిస్తుంది"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"యాక్టివిటీ విండోల సైజ్‌ మార్చ‌గ‌లిగేలా నిర్బంధించు"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"మానిఫెస్ట్ విలువలతో సంబంధం లేకుండా అన్ని యాక్టివిటీస్‌ను పలు రకాల విండోల్లో సరిపోయేటట్లు సైజ్‌ మార్చగలిగేలా చేస్తుంది."</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index c513ae7..a4e0508 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"การถ่ายโอนไฟล์"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"อุปกรณ์อินพุต"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"การเข้าถึงอินเทอร์เน็ต"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"การแชร์รายชื่อผู้ติดต่อ"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"ใช้สำหรับการแชร์รายชื่อผู้ติดต่อ"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"การแชร์การเชื่อมต่ออินเทอร์เน็ต"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"ข้อความ"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"การเข้าถึงซิม"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 9872bec..e28fd96 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Paglilipat ng file"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Device sa pag-input"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Access sa internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Pagbabahagi ng contact"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Gamitin para sa pagbabahagi ng contact"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Pagbabahagi ng koneksyon sa internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Mga Text Message"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Access sa SIM"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index ca4ccbd..05ec1cc 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Dosya aktarımı"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Giriş cihazı"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"İnternet erişimi"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kişi paylaşma"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Kişi paylaşmak için kullan"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"İnternet bağlantısı paylaşımı"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Kısa Mesajlar"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM Erişimi"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index b9599b7..184d0c1 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Передавання файлів"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Пристрій введення"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Доступ до Інтернету"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Надсилання контактів"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Використовувати для надсилання контактів"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Надання доступу до Інтернету"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Текстові повідомлення"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Доступ до SIM-карти"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index c67c8e7..419833a 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"فائل کی منتقلی"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ان پٹ آلہ"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"انٹرنیٹ تک رسائی"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"رابطہ کا اشتراک"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"رابطہ کے اشتراک کیلئے استعمال کریں"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"انٹرنیٹ کنکشن کا اشتراک کرنا"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"ٹیکسٹ پیغامات"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"‏SIM رسائی"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index e0f2897..b1e22af 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Fayl uzatish"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Kiritish qurilmasi"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetga ulanish"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktlarni ulashish"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Kontaktlarni ulashish uchun ishlatilsin"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internet aloqasi ulashmasi"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS xabarlari"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM kartaga kirish"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index fa9e57f..71bb08e 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Chuyển tệp"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Thiết bị đầu vào"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Truy cập Internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Chia sẻ người liên hệ"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Sử dụng để chia sẻ người liên hệ"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Chia sẻ kết nối internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Tin nhắn văn bản"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Truy cập SIM"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index cca21ed..f9e087b 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"文件传输"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"输入设备"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"互联网连接"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"共享联系人"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"用于共享联系人"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"共享互联网连接"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"短信"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM 卡存取权限"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index a65f77b..cd93f71 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"檔案傳輸"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"輸入裝置"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"互聯網連線"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"共用聯絡人"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"用於共用聯絡人"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"互聯網連線分享"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"短訊"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM 卡存取"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index b207326..4f36742 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"檔案傳輸"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"輸入裝置"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"網際網路連線"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"聯絡人共用"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"用於聯絡人共用"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"網際網路連線分享"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"簡訊"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM 卡存取權"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 040dfaa..88c41c5 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -117,8 +117,10 @@
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Dlulisa ifayela"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Idivaysi yokufakwayo"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Ukufinyelela i-Inthanethi"</string>
-    <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Ukwabelana kokuxhumana"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Sebenzisela ukwabelana kokuxhumana"</string>
+    <!-- no translation found for bluetooth_profile_pbap (4262303387989406171) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_pbap_summary (6466456791354759132) -->
+    <skip />
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Ukwabelana ngoxhumano lwe-Inthanethi"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Imilayezo yombhalo"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Ukufinyelela kwe-SIM"</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/src/com/android/settingslib/mobile/MobileStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/mobile/MobileStatusTracker.java
index 1a08366..b416738 100644
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/MobileStatusTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/MobileStatusTracker.java
@@ -44,6 +44,8 @@
     private final Handler mReceiverHandler;
     private final MobileTelephonyCallback mTelephonyCallback;
 
+    private boolean mListening = false;
+
     /**
      * MobileStatusTracker constructors
      *
@@ -76,6 +78,7 @@
      * Config the MobileStatusTracker to start or stop monitoring platform signals.
      */
     public void setListening(boolean listening) {
+        mListening = listening;
         if (listening) {
             mPhone.registerTelephonyCallback(mReceiverHandler::post, mTelephonyCallback);
         } else {
@@ -83,6 +86,10 @@
         }
     }
 
+    public boolean isListening() {
+        return mListening;
+    }
+
     private void updateDataSim() {
         int activeDataSubId = mDefaults.getActiveDataSubId();
         if (SubscriptionManager.isValidSubscriptionId(activeDataSubId)) {
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/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/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 8683eac..4e2bce2 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2364,6 +2364,12 @@
                 SecureSettingsProto.PowerMenuPrivacy.SHOW);
         p.end(powerMenuPrivacyToken);
 
+        final long extraLowPowerModeToken = p.start(SecureSettingsProto.EXTRA_LOW_POWER_MODE);
+        dumpSetting(s, p,
+                Settings.Secure.EXTRA_AUTOMATIC_POWER_SAVE_MODE,
+                SecureSettingsProto.ExtraLowPowerMode.EXTRA_AUTOMATIC_POWER_SAVE_MODE);
+        p.end(extraLowPowerModeToken);
+
         final long printServiceToken = p.start(SecureSettingsProto.PRINT_SERVICE);
         dumpSetting(s, p,
                 Settings.Secure.PRINT_SERVICE_SEARCH_URI,
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..4aa4006 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",
@@ -272,10 +274,12 @@
                 enabled: true,
                 optimize: true,
                 shrink: true,
+                proguard_compatibility: false,
                 proguard_flags_files: ["proguard.flags"],
             },
             conditions_default: {
                 optimize: {
+                    proguard_compatibility: false,
                     proguard_flags_files: ["proguard.flags"],
                 },
             },
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 dbdbdf6..2f36ab9 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
@@ -515,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
@@ -527,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..9671add 100644
--- a/packages/SystemUI/checks/Android.bp
+++ b/packages/SystemUI/checks/Android.bp
@@ -32,10 +32,17 @@
         "auto_service_annotations",
         "lint_api",
     ],
+    kotlincflags: ["-Xjvm-default=all"],
 }
 
 java_test_host {
     name: "SystemUILintCheckerTest",
+    // TODO(b/239881504): Since this test was written, Android
+    // Lint was updated, and now includes classes that were
+    // compiled for java 15. The soong build doesn't support
+    // java 15 yet, so we can't compile against "lint". Disable
+    // the test until java 15 is supported.
+    enabled: false,
     srcs: [
         "tests/**/*.kt",
         "tests/**/*.java",
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/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/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/combined_qs_header.xml b/packages/SystemUI/res/layout/combined_qs_header.xml
index ec82ccf..5dc34b9 100644
--- a/packages/SystemUI/res/layout/combined_qs_header.xml
+++ b/packages/SystemUI/res/layout/combined_qs_header.xml
@@ -14,7 +14,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<androidx.constraintlayout.motion.widget.MotionLayout
+<com.android.systemui.util.NoRemeasureMotionLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/split_shade_status_bar"
@@ -32,10 +32,37 @@
     <androidx.constraintlayout.widget.Guideline
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:id="@+id/center"
-        app:layout_constraintGuide_percent="0.5"
+        android:id="@+id/begin_guide"
+        android:orientation="vertical"
+        app:layout_constraintGuide_begin="0dp"/>
+
+    <androidx.constraintlayout.widget.Guideline
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/end_guide"
+        android:orientation="vertical"
+        app:layout_constraintGuide_end="0dp"
+        />
+
+    <androidx.constraintlayout.widget.Guideline
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/center_left"
         android:orientation="vertical" />
 
+    <androidx.constraintlayout.widget.Guideline
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/center_right"
+        android:orientation="vertical" />
+
+    <androidx.constraintlayout.widget.Barrier
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/barrier"
+        app:barrierDirection="start"
+        app:constraint_referenced_ids="statusIcons,privacy_container" />
+
     <com.android.systemui.statusbar.policy.Clock
         android:id="@+id/clock"
         android:layout_width="wrap_content"
@@ -44,18 +71,25 @@
         android:paddingStart="@dimen/status_bar_left_clock_starting_padding"
         android:paddingEnd="@dimen/status_bar_left_clock_end_padding"
         android:singleLine="true"
+        android:textDirection="locale"
         android:textAppearance="@style/TextAppearance.QS.Status"
+        android:transformPivotX="0sp"
+        android:transformPivotY="20sp"
+        android:scaleX="1"
+        android:scaleY="1"
     />
 
-    <com.android.systemui.statusbar.policy.DateView
+    <com.android.systemui.statusbar.policy.VariableDateView
         android:id="@+id/date"
         android:layout_width="wrap_content"
         android:layout_height="0dp"
         android:layout_gravity="start|center_vertical"
         android:gravity="center_vertical"
         android:singleLine="true"
+        android:textDirection="locale"
         android:textAppearance="@style/TextAppearance.QS.Status"
-        app:datePattern="@string/abbrev_wday_month_day_no_year_alarm"
+        app:longDatePattern="@string/abbrev_wday_month_day_no_year_alarm"
+        app:shortDatePattern="@string/abbrev_month_day_no_year"
     />
 
     <include
@@ -81,7 +115,7 @@
         app:layout_constraintHeight_min="@dimen/large_screen_shade_header_min_height"
         android:paddingEnd="@dimen/signal_cluster_battery_padding"
         android:layout_width="wrap_content"
-        android:layout_height="48dp"
+        android:layout_height="@dimen/large_screen_shade_header_min_height"
         app:layout_constraintStart_toEndOf="@id/carrier_group"
         app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
         app:layout_constraintTop_toTopOf="@id/clock"
@@ -92,8 +126,9 @@
     <com.android.systemui.battery.BatteryMeterView
         android:id="@+id/batteryRemainingIcon"
         android:layout_width="wrap_content"
-        android:layout_height="48dp"
+        android:layout_height="@dimen/large_screen_shade_header_min_height"
         app:layout_constraintHeight_min="@dimen/large_screen_shade_header_min_height"
+        app:layout_constrainedWidth="true"
         app:textAppearance="@style/TextAppearance.QS.Status"
         app:layout_constraintStart_toEndOf="@id/statusIcons"
         app:layout_constraintEnd_toEndOf="parent"
@@ -104,13 +139,18 @@
     <FrameLayout
         android:id="@+id/privacy_container"
         android:layout_width="wrap_content"
-        android:layout_height="48dp"
+        android:layout_height="@dimen/large_screen_shade_header_min_height"
         android:gravity="center"
-        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintEnd_toEndOf="@id/end_guide"
         app:layout_constraintTop_toTopOf="@id/date"
         app:layout_constraintBottom_toBottomOf="@id/date"
         >
         <include layout="@layout/ongoing_privacy_chip"/>
     </FrameLayout>
 
-</androidx.constraintlayout.motion.widget.MotionLayout>
\ No newline at end of file
+    <Space
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:id="@+id/space"
+    />
+</com.android.systemui.util.NoRemeasureMotionLayout>
\ No newline at end of file
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..a97c90c 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"
@@ -54,7 +54,6 @@
         android:layout_height="wrap_content"
         android:layout_gravity="center"
         android:background="@drawable/rounded_bg_full_large_radius"
-        android:onClick="dismissActivity"
         android:text="@string/got_it"
         android:textColor="?androidprv:attr/textColorOnAccent"
         android:layout_marginBottom="60dp"
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..d41709a 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Ontsluit met gesig. Swiep op om oop te maak."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> toestelle gekies"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ontkoppel)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan nie wissel nie. Tik om weer te probeer."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bind nuwe toestel saam"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Maak die program oop om hierdie sessie uit te saai."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Onbekende program"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Hou op uitsaai"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑fi onbeskikbaar"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteitmodus"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wekker gestel"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera en mikrofoon is af"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# kennisgewing}other{# kennisgewings}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Uitsaai"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hou op om <xliff:g id="APP_NAME">%1$s</xliff:g> uit te saai?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"As jy <xliff:g id="SWITCHAPP">%1$s</xliff:g> uitsaai of die uitvoer verander, sal jou huidige uitsending stop"</string>
     <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..8fad08f 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"እንደገና መታ ያድርጉ"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"ለመክፈት በጣት ወደ ላይ ጠረግ ያድርጉ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ለመክፈት የመክፈቻ አዶውን ይጫኑ"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"በመልክ ተከፍቷል። ለመክፈት ወደ ላይ ያንሸራትቱ።"</string>
     <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 +545,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> መሣሪያዎች ተመርጠዋል"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ተቋርጧል)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"መቀየር አይቻልም። እንደገና ለመሞከር መታ ያድርጉ።"</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"አዲስ መሣሪያ ያጣምሩ"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ይህን ክፍለ ጊዜ cast ለማድረግ፣ እባክዎ መተግበሪያውን ይክፈቱ።"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"የማይታወቅ መተግበሪያ"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Cast ማድረግ አቁም"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi አይገኝም"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"የቅድሚያ ሁነታ"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ማንቂያ ተቀናብሯል"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ካሜራ እና ማይክሮፎን ጠፍተዋል"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ማሳወቂያ}one{# ማሳወቂያዎች}other{# ማሳወቂያዎች}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"በማሰራጨት ላይ"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>ን ማሰራጨት ይቁም?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>ን ካሰራጩ ወይም ውፅዓትን ከቀየሩ የአሁኑ ስርጭትዎ ይቆማል"</string>
     <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..2439830 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"انقر مرة أخرى"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"يمكنك الفتح بالتمرير سريعًا لأعلى."</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"اضغط على رمز فتح القفل لفتح قفل الشاشة."</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"تم فتح قفل جهازك عند تقريبه من وجهك. مرِّر سريعًا للأعلى لفتح الجهاز."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"تم اختيار <xliff:g id="COUNT">%1$d</xliff:g> جهاز."</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(غير متّصل)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"لا يمكن التبديل. انقر لإعادة المحاولة."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"إقران جهاز جديد"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"لبث هذه الجلسة، يُرجى فتح التطبيق"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"تطبيق غير معروف"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"إيقاف البث"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‏شبكة Wi‑Fi غير متاحة"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"وضع الأولوية"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"تم ضبط المنبه."</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"الكاميرا والميكروفون غير مفعّلين."</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{إشعار واحد}zero{# إشعار}two{إشعاران}few{# إشعارات}many{# إشعارًا}other{# إشعار}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"البث"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"هل تريد إيقاف بث تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g>؟"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"إذا أجريت بث تطبيق <xliff:g id="SWITCHAPP">%1$s</xliff:g> أو غيَّرت جهاز الإخراج، سيتوقَف البث الحالي."</string>
     <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..2fda54f 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"পুনৰ টিপক"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"খুলিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"খুলিবলৈ আনলক কৰক চিহ্নটোত টিপক"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা। খুলিবলৈ ওপৰলৈ ছোৱাইপ কৰক।"</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> টা ডিভাইচ বাছনি কৰা হৈছে"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(সংযোগ বিচ্ছিন্ন কৰা হৈছে)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"সলনি কৰিব নোৱাৰি। আকৌ চেষ্টা কৰিবলৈ টিপক।"</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"নতুন ডিভাইচ পেয়াৰ কৰক"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"এই ছেশ্বনটো কাষ্ট কৰিবলৈ, অনুগ্ৰহ কৰি এপ্‌টো খোলক"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"অজ্ঞাত এপ্"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"কাষ্ট বন্ধ কৰক"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ৱাই-ফাই উপলব্ধ নহয়"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"অগ্ৰাধিকাৰ ম’ড"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"এলাৰ্ম ছেট কৰা হ’ল"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"কেমেৰা আৰু মাইক অফ হৈ আছে"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# টা জাননী}one{# টা জাননী}other{# টা জাননী}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"সম্প্ৰচাৰণ"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ সম্প্ৰচাৰ কৰা বন্ধ কৰিবনে?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"যদি আপুনি <xliff:g id="SWITCHAPP">%1$s</xliff:g>ৰ সম্প্ৰচাৰ কৰে অথবা আউটপুট সলনি কৰে, তেন্তে, আপোনাৰ বৰ্তমানৰ সম্প্ৰচাৰ বন্ধ হৈ যাব"</string>
     <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..bbf3c89 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Üz ilə kiliddən çıxarılıb. Açmaq üçün yuxarı sürüşdürün."</string>
     <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>
@@ -833,7 +831,7 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> cihaz seçilib"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(bağlantı kəsildi)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Dəyişmək olmur. Yenidən cəhd etmək üçün toxunun."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Cihaz əlavə edin"</string>
+    <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Cihaz qoşun"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu sessiyanı yayımlamaq üçün tətbiqi açın."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Naməlum tətbiq"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Yayımı dayandırın"</string>
@@ -945,12 +943,18 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi əlçatan deyil"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritet rejimi"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Siqnal ayarlanıb"</string>
+    <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera deaktivdir"</string>
+    <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon deaktivdir"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera və mikrofon deaktivdir"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# bildiriş}other{# bildiriş}}"</string>
+    <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Yayım"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinin yayımlanması dayandırılsın?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlasanız və ya nəticəni dəyişsəniz, cari yayımınız dayandırılacaq"</string>
     <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..80a812d 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Otključano je licem. Prevucite nagore da biste otvorili."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Izabranih uređaja: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(veza je prekinuta)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Prebacivanje nije uspelo. Probajte ponovo."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Upari novi uređaj"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da biste prebacivali ovu sesiju, otvorite aplikaciju."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zaustavi prebacivanje"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi nije dostupan"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetni režim"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je podešen"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera i mikrofon su isključeni"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obaveštenje}one{# obaveštenje}few{# obaveštenja}other{# obaveštenja}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitovanje"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Želite da zaustavite emitovanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitujete aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promenite izlaz, aktuelno emitovanje će se zaustaviti"</string>
     <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..35925a8 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"Націсніце яшчэ раз"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Каб адкрыць, прагарніце ўверх"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Каб адкрыць, націсніце значок разблакіроўкі"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Твар распазнаны. Каб адкрыць, прагарніце ўверх."</string>
     <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 +372,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Выбрана прылад: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(адключана)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не ўдалося пераключыцца. Дакраніцеся, каб паўтарыць спробу."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Спалучыць з новай прыладай"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Для трансляцыі гэтага сеанса адкрыйце праграму."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Невядомая праграма"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Спыніць трансляцыю"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Сетка Wi‑Fi недаступная"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Прыярытэтны рэжым"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будзільнік зададзены"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера і мікрафон выключаны"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# апавяшчэнне}one{# апавяшчэнне}few{# апавяшчэнні}many{# апавяшчэнняў}other{# апавяшчэння}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Перадача даных"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Спыніць трансляцыю праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Пры пераключэнні на праграму \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\" ці змяненні вываду бягучая трансляцыя спыняецца"</string>
     <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..2277ba2 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"Докоснете отново"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Прекарайте пръст нагоре, за да отключите"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Натиснете иконата за отключване, за да отворите"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Отключено с лице. Прекарайте пръст нагоре за отваряне."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> избрани устройства"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(връзката е прекратена)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не може да се превключи. Докоснете за нов опит."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Сдвояване на ново устройство"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"За да предавате тази сесия, моля, отворете приложението."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Неизвестно приложение"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Спиране на предаването"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi не е налице"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетен режим"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будилникът е зададен"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камерата и микрофонът са изключени"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# известие}other{# известия}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Излъчване"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Да се спре ли предаването на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако предавате <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените изхода, текущото ви предаване ще бъде прекратено"</string>
     <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..0f82d07 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"আবার ট্যাপ করুন"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"খোলার জন্য উপরে সোয়াইপ করুন"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"খোলার জন্য আনলক আইকন প্রেস করুন"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"মুখের মাধ্যমে আনলক করা হয়েছে। খুলতে উপরের দিকে সোয়াইপ করুন।"</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g>টি ডিভাইস বেছে নেওয়া হয়েছে"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ডিসকানেক্ট হয়ে গেছে)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"পাল্টানো যাচ্ছে না। আবার চেষ্টা করতে ট্যাপ করুন।"</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"নতুন ডিভাইস পেয়ার করুন"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"এই সেশন কাস্ট করার জন্য, অ্যাপ খুলুন।"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"অজানা অ্যাপ"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"কাস্ট করা বন্ধ করুন"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ওয়াই-ফাই উপলভ্য নেই"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"প্রায়োরিটি মোড"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"অ্যালার্ম সেট করা হয়েছে"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ক্যামেরা ও মাইক্রোফোন বন্ধ আছে"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{#টি বিজ্ঞপ্তি}one{#টি বিজ্ঞপ্তি}other{#টি বিজ্ঞপ্তি}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ব্রডকাস্ট করা হচ্ছে"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> সম্প্রচার বন্ধ করবেন?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"আপনি <xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্রচার করলে বা আউটপুট পরিবর্তন করলে, আপনার বর্তমান সম্প্রচার বন্ধ হয়ে যাবে"</string>
     <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..cabdb0b 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Otključano licem. Prevucite nagore da otvorite."</string>
     <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 +372,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Broj odabranih uređaja: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(veza je prekinuta)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nije moguće prebaciti. Dodirnite da pokušate ponovo."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uparite novi uređaj"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da emitirate ovu sesiju, otvorite aplikaciju."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zaustavi emitiranje"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi je nedostupan"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Način rada Prioriteti"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je postavljen"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera i mikrofon su isključeni"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obavještenje}one{# obavještenje}few{# obavještenja}other{# obavještenja}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiranje"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zaustaviti emitiranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitirate aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promijenite izlaz, trenutno emitiranje će se zaustaviti"</string>
     <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..eaeec2e 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"S\'ha desbloquejat amb la cara. Llisca cap amunt per obrir."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"S\'han seleccionat <xliff:g id="COUNT">%1$d</xliff:g> dispositius"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconnectat)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"No es pot canviar. Torna-ho a provar."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincula un dispositiu nou"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Per emetre aquesta sessió, obre l\'aplicació."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicació desconeguda"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Atura l\'emissió"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi no disponible"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode Prioritat"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma definida"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Càmera i micròfon desactivats"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificació}other{# notificacions}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"S\'està emetent"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vols deixar d\'emetre <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si emets <xliff:g id="SWITCHAPP">%1$s</xliff:g> o canvies la sortida, l\'emissió actual s\'aturarà"</string>
     <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..934ba3a 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Odemknuto obličejem. Otevřete přejetím prstem nahoru."</string>
     <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 +372,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Vybraná zařízení: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(odpojeno)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nelze přepnout. Klepnutím opakujte akci."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Spárovat nové zařízení"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pokud chcete odesílat relaci, otevřete aplikaci."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznámá aplikace"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zastavit odesílání"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Síť Wi‑Fi není k dispozici"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritní režim"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Je nastaven budík"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparát a mikrofon jsou vypnuté"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# oznámení}few{# oznámení}many{# oznámení}other{# oznámení}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Vysílání"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zastavit vysílání v aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Pokud budete vysílat v aplikaci <xliff:g id="SWITCHAPP">%1$s</xliff:g> nebo změníte výstup, aktuální vysílání se zastaví"</string>
     <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..ff007b9 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Låst op ved hjælp af ansigt. Stryg opad for at åbne."</string>
     <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 +372,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Der er valgt <xliff:g id="COUNT">%1$d</xliff:g> enhed"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(afbrudt)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Det var ikke muligt at skifte. Tryk for at prøve igen."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Par ny enhed"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Åbn appen for at caste denne session."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ukendt app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop med at caste"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Ingen tilgængelig Wi-Fi-forbindelse"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Tilstanden Prioritet"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmen er indstillet"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera og mikrofon er slået fra"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifikation}one{# notifikation}other{# notifikationer}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Udsender"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop udsendelsen <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Hvis du udsender <xliff:g id="SWITCHAPP">%1$s</xliff:g> eller skifter output, stopper din aktuelle udsendelse"</string>
     <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..40e47a5 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Gerät mit Gesicht entsperrt. Zum Öffnen nach oben wischen."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> Geräte ausgewählt"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(nicht verbunden)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Wechseln nicht möglich. Tippe, um es noch einmal zu versuchen."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Neues Gerät koppeln"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Öffne zum Streamen dieser Sitzung die App."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unbekannte App"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Streaming beenden"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WLAN nicht verfügbar"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritätsmodus"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wecker gestellt"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera und Mikrofon ausgeschaltet"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# Benachrichtigung}other{# Benachrichtigungen}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Übertragung läuft"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> nicht mehr streamen?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Wenn du <xliff:g id="SWITCHAPP">%1$s</xliff:g> streamst oder die Ausgabe änderst, wird dein aktueller Stream beendet"</string>
     <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..4670fc7 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"Πατήστε ξανά"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Σύρετε προς τα επάνω για άνοιγμα"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Πατήστε το εικονίδιο ξεκλειδώματος για άνοιγμα"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Ξεκλ. με αναγν. προσώπου. Σύρετε προς τα επάνω για άνοιγμα."</string>
     <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 +372,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>
@@ -833,7 +831,7 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Επιλέχτηκαν <xliff:g id="COUNT">%1$d</xliff:g> συσκευές"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(αποσυνδέθηκε)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Δεν είναι δυνατή η εναλλαγή. Πατήστε για επανάληψη."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Σύζευξη νέας συσκευής"</string>
+    <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Σύνδεση συσκευής"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Για μετάδοση της περιόδου σύνδεσης, ανοίξτε την εφαρμογή."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Άγνωστη εφαρμογή"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Διακοπή μετάδοσης"</string>
@@ -945,12 +943,18 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Το Wi‑Fi δεν είναι διαθέσιμο"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Λειτουργία προτεραιότητας"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Το ξυπνητήρι ρυθμίστηκε"</string>
+    <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Η κάμερα είναι απενεργοποιημένη"</string>
+    <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Το μικρόφωνο είναι απενεργοποιημένο"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Η κάμερα και το μικρόφωνο έχουν απενεργοποιηθεί"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ειδοποίηση}other{# ειδοποιήσεις}}"</string>
+    <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Μετάδοση"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Διακοπή μετάδοσης με την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Εάν κάνετε μετάδοση με την εφαρμογή <xliff:g id="SWITCHAPP">%1$s</xliff:g> ή αλλάξετε την έξοδο, η τρέχουσα μετάδοση θα σταματήσει"</string>
     <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..2139344 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -30,7 +30,7 @@
     <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"About Battery Saver"</string>
     <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Turn on"</string>
     <string name="battery_saver_start_action" msgid="8353766979886287140">"Turn on"</string>
-    <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No thanks"</string>
+    <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, thanks"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Auto-rotate screen"</string>
     <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
     <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
@@ -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>
@@ -786,7 +784,7 @@
     <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"You can add controls for your external devices to the lock screen.\n\nYour device app may allow you to control some devices without unlocking your phone or tablet.\n\nYou can make changes at any time in Settings."</string>
     <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Control devices from the lock screen?"</string>
     <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"You can control some devices without unlocking your phone or tablet.\n\nYour device app determines which devices can be controlled in this way."</string>
-    <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No thanks"</string>
+    <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No, thanks"</string>
     <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Yes"</string>
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string>
     <string name="controls_pin_verify" msgid="3452778292918877662">"Verify <xliff:g id="DEVICE">%s</xliff:g>"</string>
@@ -833,7 +831,7 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> devices selected"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
+    <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connect a device"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop casting"</string>
@@ -945,12 +943,18 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi unavailable"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
+    <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Camera is off"</string>
+    <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mic is off"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera and mic are off"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
+    <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
     <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..84f337b 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -30,7 +30,7 @@
     <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"About Battery Saver"</string>
     <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Turn on"</string>
     <string name="battery_saver_start_action" msgid="8353766979886287140">"Turn on"</string>
-    <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No thanks"</string>
+    <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, thanks"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Auto-rotate screen"</string>
     <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
     <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
@@ -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>
@@ -786,7 +784,7 @@
     <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"You can add controls for your external devices to the lock screen.\n\nYour device app may allow you to control some devices without unlocking your phone or tablet.\n\nYou can make changes at any time in Settings."</string>
     <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Control devices from the lock screen?"</string>
     <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"You can control some devices without unlocking your phone or tablet.\n\nYour device app determines which devices can be controlled in this way."</string>
-    <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No thanks"</string>
+    <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No, thanks"</string>
     <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Yes"</string>
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string>
     <string name="controls_pin_verify" msgid="3452778292918877662">"Verify <xliff:g id="DEVICE">%s</xliff:g>"</string>
@@ -833,7 +831,7 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> devices selected"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
+    <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connect a device"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop casting"</string>
@@ -945,12 +943,18 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi unavailable"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
+    <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Camera is off"</string>
+    <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mic is off"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera and mic are off"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
+    <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
     <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..2139344 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -30,7 +30,7 @@
     <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"About Battery Saver"</string>
     <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Turn on"</string>
     <string name="battery_saver_start_action" msgid="8353766979886287140">"Turn on"</string>
-    <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No thanks"</string>
+    <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, thanks"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Auto-rotate screen"</string>
     <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
     <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
@@ -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>
@@ -786,7 +784,7 @@
     <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"You can add controls for your external devices to the lock screen.\n\nYour device app may allow you to control some devices without unlocking your phone or tablet.\n\nYou can make changes at any time in Settings."</string>
     <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Control devices from the lock screen?"</string>
     <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"You can control some devices without unlocking your phone or tablet.\n\nYour device app determines which devices can be controlled in this way."</string>
-    <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No thanks"</string>
+    <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No, thanks"</string>
     <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Yes"</string>
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string>
     <string name="controls_pin_verify" msgid="3452778292918877662">"Verify <xliff:g id="DEVICE">%s</xliff:g>"</string>
@@ -833,7 +831,7 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> devices selected"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
+    <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connect a device"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop casting"</string>
@@ -945,12 +943,18 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi unavailable"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
+    <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Camera is off"</string>
+    <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mic is off"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera and mic are off"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
+    <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
     <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..2139344 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -30,7 +30,7 @@
     <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"About Battery Saver"</string>
     <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Turn on"</string>
     <string name="battery_saver_start_action" msgid="8353766979886287140">"Turn on"</string>
-    <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No thanks"</string>
+    <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, thanks"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Auto-rotate screen"</string>
     <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
     <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
@@ -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>
@@ -786,7 +784,7 @@
     <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"You can add controls for your external devices to the lock screen.\n\nYour device app may allow you to control some devices without unlocking your phone or tablet.\n\nYou can make changes at any time in Settings."</string>
     <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Control devices from the lock screen?"</string>
     <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"You can control some devices without unlocking your phone or tablet.\n\nYour device app determines which devices can be controlled in this way."</string>
-    <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No thanks"</string>
+    <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No, thanks"</string>
     <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Yes"</string>
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string>
     <string name="controls_pin_verify" msgid="3452778292918877662">"Verify <xliff:g id="DEVICE">%s</xliff:g>"</string>
@@ -833,7 +831,7 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> devices selected"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
+    <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connect a device"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop casting"</string>
@@ -945,12 +943,18 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi unavailable"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
+    <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Camera is off"</string>
+    <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mic is off"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera and mic are off"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
+    <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
     <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..c8d0442 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>
@@ -833,7 +831,7 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‏‏‎‏‏‎‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="COUNT">%1$d</xliff:g>‎‏‎‎‏‏‏‎ devices selected‎‏‎‎‏‎"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎(disconnected)‎‏‎‎‏‎"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎Can\'t switch. Tap to try again.‎‏‎‎‏‎"</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎‎Pair new device‎‏‎‎‏‎"</string>
+    <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‎‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‏‎‎Connect a device‎‏‎‎‏‎"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‏‎To cast this session, please open the app.‎‏‎‎‏‎"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎Unknown app‎‏‎‎‏‎"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‏‎‏‎Stop casting‎‏‎‎‏‎"</string>
@@ -945,12 +943,18 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‏‏‏‏‎‎Wi‑Fi unavailable‎‏‎‎‏‎"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‏‏‏‎‎‏‎‎‎‏‏‎Priority mode‎‏‎‎‏‎"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‏‎‎Alarm set‎‏‎‎‏‎"</string>
+    <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‏‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‏‎Camera is off‎‏‎‎‏‎"</string>
+    <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎Mic is off‎‏‎‎‏‎"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‎‎‎‏‎Camera and mic are off‎‏‎‎‏‎"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎# notification‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎# notifications‎‏‎‎‏‎}}"</string>
+    <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="TEMPERATURE">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‎Broadcasting‎‏‎‎‏‎"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‎‎‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎‏‏‎Stop broadcasting ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‎‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎If you broadcast ‎‏‎‎‏‏‎<xliff:g id="SWITCHAPP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ or change the output, your current broadcast will stop‎‏‎‎‏‎"</string>
     <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..869e3b9 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Desbloqueo con rostro. Desliza hacia arriba para abrir."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Se seleccionaron <xliff:g id="COUNT">%1$d</xliff:g> dispositivos"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconectado)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"No se pudo conectar. Presiona para volver a intentarlo."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular dispositivo nuevo"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para transmitir esta sesión, abre la app"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconocida"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Detener transmisión"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"La red Wi-Fi no está disponible"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo prioridad"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Se estableció la alarma"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"La cámara y el micrófono están apagados"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}other{# notificaciones}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmitiendo"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"¿Quieres dejar de transmitir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si transmites <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambias la salida, tu transmisión actual se detendrá"</string>
     <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..1899940 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Desbloqueado con la cara. Desliza hacia arriba para abrir."</string>
     <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 +400,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> dispositivos seleccionados"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconectado)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"No se puede cambiar. Toca para volver a intentarlo."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Emparejar nuevo dispositivo"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para enviar esta sesión, abre la aplicación."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicación desconocida"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Dejar de enviar contenido"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi no disponible"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo prioritario"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma añadida"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"La cámara y el micrófono están desactivados"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}other{# notificaciones}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiendo"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"¿Dejar de emitir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si emites <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambias la salida, tu emisión actual se detendrá"</string>
     <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..ffeb8b9 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Avati näoga. Pühkige avamiseks üles."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> seadet on valitud"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ühendus on katkestatud)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ei saa lülitada. Puudutage uuesti proovimiseks."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uue seadme sidumine"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Selle seansi ülekandmiseks avage rakendus."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Tundmatu rakendus"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Lõpeta ülekanne"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi pole saadaval"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Režiim Prioriteetne"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm on määratud"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kaamera ja mikrofon on välja lülitatud"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# märguanne}other{# märguannet}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Edastamine"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Kas peatada rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> ülekandmine?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Kui kannate rakendust <xliff:g id="SWITCHAPP">%1$s</xliff:g> üle või muudate väljundit, peatatakse teie praegune ülekanne"</string>
     <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..dac1f25 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Aurpegiaren bidez desblokeatu da. Irekitzeko, pasatu hatza gora."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> gailu hautatu dira"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(deskonektatuta)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ezin da aldatu. Berriro saiatzeko, sakatu hau."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parekatu beste gailu batekin"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Saioa ireki nahi baduzu, ireki aplikazioa."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikazio ezezaguna"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Gelditu igorpena"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wifi-konexioa ez dago erabilgarri"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Lehentasun modua"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma ezarrita dago"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera eta mikrofonoa desaktibatuta daude"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# jakinarazpen}other{# jakinarazpen}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Igortzen"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren audioa igortzeari utzi nahi diozu?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> aplikazioaren audioa igortzen baduzu, edo audio-irteera aldatzen baduzu, une hartako igorpena eten egingo da"</string>
     <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..8a102b7 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"دوباره ضربه بزنید"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"برای باز کردن، انگشتتان را تند به‌بالا بکشید"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"برای باز کردن، نماد قفل‌گشایی را فشار دهید"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"قفلْ با چهره باز شد. برای باز کردن، تند به‌بالا بکشید."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> دستگاه انتخاب شد"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(اتصال قطع شد)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"عوض نمی‌شود. برای تلاش مجدد ضربه بزنید."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"مرتبط کردن دستگاه جدید"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"برای ارسال محتوای این جلسه، لطفاً برنامه را باز کنید."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"برنامه ناشناس"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"توقف پخش محتوا"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‏Wi‑Fi دردسترس نیست"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"حالت اولویت"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"زنگ ساعت تنظیم شد"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"دوربین و میکروفون خاموش هستند"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# اعلان}one{# اعلان}other{# اعلان}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"همه‌فرستی"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"همه‌فرستی <xliff:g id="APP_NAME">%1$s</xliff:g> متوقف شود؟"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"اگر <xliff:g id="SWITCHAPP">%1$s</xliff:g> را همه‌فرستی کنید یا خروجی را تغییر دهید، همه‌فرستی کنونی متوقف خواهد شد"</string>
     <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..d860318 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Avattu kasvojen avulla. Avaa pyyhkäisemällä ylös."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> laitetta valittu"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(yhteys katkaistu)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Vaihtaminen ei onnistunut. Yritä uudelleen."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Muodosta uusi laitepari"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Jos haluat striimata tämän käyttökerran, avaa sovellus."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Tuntematon sovellus"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Lopeta striimaus"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ei ole saatavilla"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Tärkeät-tila"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Hälytys asetettu"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera ja mikrofoni ovat pois päältä"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ilmoitus}other{# ilmoitusta}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Lähettää"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Lopetetaanko <xliff:g id="APP_NAME">%1$s</xliff:g>-sovelluksen lähettäminen?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jos lähetät <xliff:g id="SWITCHAPP">%1$s</xliff:g>-sovellusta tai muutat ulostuloa, nykyinen lähetyksesi loppuu"</string>
     <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..e9b6f4a 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Déverrouillé par le visage. Balayez vers le haut pour ouvrir."</string>
     <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 +372,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> appareil sélectionné"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(déconnecté)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Changement impossible. Touchez pour réessayer."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un autre appareil"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pour diffuser cette session, veuillez ouvrir l\'application."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Application inconnue"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Arrêter la diffusion"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi non disponible"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode priorité"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"L\'alarme a été réglée"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"L\'appareil photo et le micro sont désactivés"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}other{# notifications}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Diffusion en cours…"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Arrêter la diffusion de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou changez la sortie, votre diffusion actuelle s\'arrêtera"</string>
     <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..ea38bcf6 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Déverrouillé par visage. Balayez vers le haut pour ouvrir."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> appareils sélectionnés"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(déconnecté)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Impossible de changer. Appuyez pour réessayer."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un nouvel appareil"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pour caster cette session, veuillez ouvrir l\'appli."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Appli inconnue"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Arrêter la diffusion"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi non disponible"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode Prioritaire"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme réglée"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Appareil photo et micro désactivés"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}other{# notifications}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Diffusion…"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Arrêter la diffusion de <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou que vous modifiez le résultat, votre annonce actuelle s\'arrêtera"</string>
     <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..d928a0f 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Desbloqueado coa cara. Pasa o dedo cara arriba para acceder."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Seleccionáronse <xliff:g id="COUNT">%1$d</xliff:g> dispositivos"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconectado)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Non se puido realizar o cambio. Toca para tentalo de novo."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular dispositivo novo"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para emitir esta sesión, abre a aplicación."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicación descoñecida"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Deter emisión"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"A wifi non está dispoñible"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo de prioridade"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma definida"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A cámara e o micrófono están desactivados"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}other{# notificacións}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Difusión"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Queres deixar de emitir contido a través de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se emites contido a través de <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou cambias de saída, a emisión en curso deterase"</string>
     <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..b22f414 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"ફરીથી ટૅપ કરો"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"ખોલવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ખોલવા માટે \'અનલૉક કરો\' આઇકન દબાવો"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"ચહેરા દ્વારા અનલૉક કર્યું. ખોલવા માટે ઉપરની તરફ સ્વાઇપ કરો."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> ડિવાઇસ પસંદ કર્યા"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ડિસ્કનેક્ટ કરેલું)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"સ્વિચ કરી શકતા નથી. ફરી પ્રયાસ કરવા માટે ટૅપ કરો."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"નવા ડિવાઇસ સાથે જોડાણ કરો"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"આ સત્ર કાસ્ટ કરવા માટે, કૃપા કરીને ઍપ ખોલો."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"અજાણી ઍપ"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"કાસ્ટ કરવાનું રોકો"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"વાઇ-ફાઇ ઉપલબ્ધ નથી"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"પ્રાધાન્યતા મોડ"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"અલાર્મ સેટ"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"કૅમેરા અને માઇક બંધ છે"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# નોટિફિકેશન}one{# નોટિફિકેશન}other{# નોટિફિકેશન}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"બ્રૉડકાસ્ટ કરી રહ્યાં છે"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> બ્રોડકાસ્ટ કરવાનું રોકીએ?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"જો તમે <xliff:g id="SWITCHAPP">%1$s</xliff:g> બ્રોડકાસ્ટ કરો અથવા આઉટપુટ બદલો, તો તમારું હાલનું બ્રોડકાસ્ટ બંધ થઈ જશે"</string>
     <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..5fa1540 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>
@@ -246,7 +243,7 @@
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"रंग में सुधार करने की सुविधा"</string>
     <string name="quick_settings_more_user_settings" msgid="1064187451100861954">"उपयोगकर्ता सेटिंग"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"हो गया"</string>
-    <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"बंद करें"</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_connecting" msgid="2381969772953268809">"कनेक्ट हो रहा है..."</string>
@@ -310,6 +307,7 @@
     <string name="tap_again" msgid="1315420114387908655">"फिर से टैप करें"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"खोलने के लिए ऊपर स्वाइप करें"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"डिवाइस अनलॉक करने के लिए, अनलॉक आइकॉन को दबाएं"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"चेहरे से अनलॉक किया गया. खोलने के लिए ऊपर की ओर स्वाइप करें."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> डिवाइस चुने गए"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(डिसकनेक्ट हो गया)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"स्विच नहीं किया जा सकता. फिर से कोशिश करने के लिए टैप करें."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नया डिवाइस जोड़ें"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"इस सेशन को कास्ट करने के लिए, कृपया ऐप्लिकेशन खोलें."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अनजान ऐप्लिकेशन"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"कास्टिंग करना रोकें"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"वाई-फ़ाई उपलब्ध नहीं है"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"प्राथमिकता मोड"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट किया गया"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"कैमरा और माइक बंद हैं"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# सूचना}one{# सूचना}other{# सूचनाएं}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ब्रॉडकास्ट ऐप्लिकेशन"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> पर ब्रॉडकास्ट करना रोकें?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> पर ब्रॉडकास्ट शुरू करने पर या आउटपुट बदलने पर, आपका मौजूदा ब्रॉडकास्ट बंद हो जाएगा"</string>
     <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..bbf02ca 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Otključano licem. Prijeđite prstom prema gore za otvaranje."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Odabrano uređaja: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(nije povezano)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nije prebačeno. Dodirnite da biste pokušali ponovo."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uparite novi uređaj"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da biste emitirali ovu sesiju, otvorite aplikaciju."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zaustavi emitiranje"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nije dostupan"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetni način rada"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je postavljen"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparat i mikrofon su isključeni"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obavijest}one{# obavijest}few{# obavijesti}other{# obavijesti}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiranje"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zaustaviti emitiranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitirate aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promijenite izlaz, vaše će se trenutačno emitiranje zaustaviti"</string>
     <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..e4cf922 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Zárolás arccal feloldva. Csúsztasson felfelé a megnyitáshoz."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> eszköz kiválasztva"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(leválasztva)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"A váltás nem sikerült. Próbálja újra."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Új eszköz párosítása"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"A munkamenet átküldéséhez nyissa meg az alkalmazást."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ismeretlen alkalmazás"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Átküldés leállítása"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"A Wi‑Fi nem áll rendelkezésre"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritás mód"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Ébresztő beállítva"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A kamera és a mikrofon ki vannak kapcsolva"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# értesítés}other{# értesítés}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Sugárzás"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Leállítja a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> közvetítését?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"A(z) <xliff:g id="SWITCHAPP">%1$s</xliff:g> közvetítése vagy a kimenet módosítása esetén a jelenlegi közvetítés leáll"</string>
     <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..5d1563d 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"Նորից հպեք"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Բացելու համար սահեցրեք վերև"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Բացեք՝ սեղմելով ապակողպման պատկերակը"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Ապակողպվել է դեմքով։ Բացելու համար սահեցրեք մատը վերև։"</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Ընտրված է <xliff:g id="COUNT">%1$d</xliff:g> սարք"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(անջատված է)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Սխալ առաջացավ։ Հպեք՝ կրկնելու համար։"</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Նոր սարքի զուգակցում"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Այս աշխատաշրջանը հեռարձակելու համար բացեք հավելվածը"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Անհայտ հավելված"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Կանգնեցնել հեռարձակումը"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi-ը հասանելի չէ"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Առաջնահերթության ռեժիմ"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Զարթուցիչը դրված է"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Տեսախցիկը և խոսափողն անջատված են"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ծանուցում}one{# ծանուցում}other{# ծանուցում}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Հեռարձակում"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Կանգնեցնել <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի հեռարձակումը"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Եթե հեռարձակեք <xliff:g id="SWITCHAPP">%1$s</xliff:g> հավելվածը կամ փոխեք աուդիո ելքը, ձեր ընթացիկ հեռարձակումը կկանգնեցվի։"</string>
     <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..99bf503 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Kunci dibuka dengan wajah. Geser ke atas untuk membuka."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> perangkat dipilih"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(terputus)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Tidak dapat beralih. Ketuk untuk mencoba lagi."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sambungkan perangkat baru"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Buka aplikasi untuk mentransmisikan sesi ini."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikasi tidak dikenal"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Hentikan transmisi"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi tidak tersedia"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode prioritas"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm disetel"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dan mikrofon nonaktif"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifikasi}other{# notifikasi}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Menyiarkan"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hentikan siaran <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jika Anda menyiarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g> atau mengubah output, siaran saat ini akan dihentikan"</string>
     <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..38982e1 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Opnað með andliti. Strjúktu upp til að opna."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> tæki valin"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(aftengt)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ekki er hægt að skipta. Ýttu til að reyna aftur."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Para nýtt tæki"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Opnaðu forritið til að senda þessa lotu út."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Óþekkt forrit"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stöðva útsendingu"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi ekki tiltækt"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Forgangsstilling"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Vekjari stilltur"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Slökkt á myndavél og hljóðnema"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# tilkynning}one{# tilkynning}other{# tilkynningar}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Útsending í gangi"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hætta að senda út <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ef þú sendir út <xliff:g id="SWITCHAPP">%1$s</xliff:g> eða skiptir um úttak lýkur yfirstandandi útsendingu"</string>
     <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..5caaa60 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Sbloccato con il volto. Scorri verso l\'alto per aprire."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> dispositivi selezionati"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnesso)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Non puoi cambiare. Tocca per riprovare."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Accoppia nuovo dispositivo"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Per trasmettere questa sessione devi aprire l\'app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App sconosciuta"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Interrompi trasmissione"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi non disponibile"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modalità Priorità"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Sveglia impostata"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotocamera e microfono non attivi"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifica}other{# notifiche}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Trasmissione in corso…"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vuoi interrompere la trasmissione dell\'app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se trasmetti l\'app <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambi l\'uscita, la trasmissione attuale viene interrotta"</string>
     <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>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM g"</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-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index a889c9c..98834a9 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"צריך להקיש פעם נוספת"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"צריך להחליק כדי לפתוח"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"לפתיחה, לוחצים על סמל ביטול הנעילה"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"הנעילה בוטלה באמצעות זיהוי הפנים. צריך להחליק כדי לפתוח."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"נבחרו <xliff:g id="COUNT">%1$d</xliff:g> מכשירים"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(מנותק)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"לא ניתן להחליף. צריך להקיש כדי לנסות שוב."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"התאמה של מכשיר חדש"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"‏כדי להעביר (cast) את הסשן הזה, צריך לפתוח את האפליקציה."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"אפליקציה לא ידועה"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"‏עצירת ההעברה (casting)"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‏Wi‑Fi לא זמין"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"מצב עדיפות"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ההתראה מוגדרת"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"המצלמה והמיקרופון כבויים"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{התראה אחת}two{# התראות}many{# התראות}other{# התראות}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"שידור"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"האם להפסיק לשדר את התוכן מאפליקציית <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"אם משדרים את התוכן מאפליקציית <xliff:g id="SWITCHAPP">%1$s</xliff:g> או משנים את הפלט, השידור הנוכחי יפסיק לפעול"</string>
     <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..564e911 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"もう一度タップしてください"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"開くには上にスワイプします"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ロック解除アイコンを押して開きます"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"顔でロック解除しました。開くには上にスワイプします。"</string>
     <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 +372,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"選択したデバイス: <xliff:g id="COUNT">%1$d</xliff:g> 台"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(接続解除済み)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"切り替えられません。タップしてやり直してください。"</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"新しいデバイスとのペア設定"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"このセッションをキャストするには、アプリを開いてください。"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明なアプリ"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"キャストを停止"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi を利用できません"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"優先順位モード"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"アラームを設定しました"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"カメラとマイクが OFF です"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 件の通知}other{# 件の通知}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ブロードキャスト"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> のブロードキャストを停止しますか?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> をブロードキャストしたり、出力を変更したりすると、現在のブロードキャストが停止します。"</string>
     <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..8d0257c 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"შეეხეთ ხელახლა"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"გასახსნელად გადაფურცლეთ ზემოთ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"გასახსნელად დააჭირეთ განბლოკვის ხატულას"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"განიბლოკა სახით. გასახსნელად აწიეთ ზემოთ"</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"არჩეულია <xliff:g id="COUNT">%1$d</xliff:g> მოწყობილობა"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(კავშირი გაწყვეტილია)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ვერ გადაირთო. შეეხეთ ხელახლა საცდელად."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ახალი მოწყობილობის დაწყვილება"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ამ სესიის ტრანსლირებისთვის გახსენით აპი."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"უცნობი აპი"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ტრანსლირების შეწყვეტა"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi მიუწვდომელია"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"პრიორიტეტული რეჟიმი"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"მაღვიძარა დაყენებულია"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"კამერა და მიკროფონი გამორთულია"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# შეტყობინება}other{# შეტყობინება}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"იწყებთ მაუწყებლობას"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"გსურთ <xliff:g id="APP_NAME">%1$s</xliff:g>-ის ტრანსლაციის შეჩერება?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-ის ტრანსლაციის შემთხვევაში ან აუდიოს გამოსასვლელის შეცვლისას, მიმდინარე ტრანსლაცია შეჩერდება"</string>
     <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..68a180a 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"Қайта түртіңіз."</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Ашу үшін жоғары қарай сырғытыңыз."</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Ашу үшін құлыпты ашу белгішесін басыңыз."</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Бетпен ашылды. Ашу үшін жоғары қарай сырғытыңыз."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> құрылғы таңдалды."</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ажыратулы)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ауысу мүмкін емес. Әрекетті қайталау үшін түртіңіз."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңа құрылғымен жұптау"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Бұл сеансты трансляциялау үшін қолданбаны ашыңыз."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Белгісіз қолданба"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Трансляцияны тоқтату"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi қолжетімсіз"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Басымдық режимі"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Оятқыш орнатылды"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера мен микрофон өшірулі"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# хабарландыру}other{# хабарландыру}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Таратуда"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын таратуды тоқтатасыз ба?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын таратсаңыз немесе аудио шығысын өзгертсеңіз, қазіргі тарату сеансы тоқтайды."</string>
     <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..16396ec 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"ចុច​ម្ដងទៀត"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"អូសឡើងលើ​ដើម្បីបើក"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ចុចរូបដោះសោ ដើម្បីបើក"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"បានដោះសោដោយប្រើមុខ។ អូសឡើងលើ​ដើម្បីបើក។"</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"បានជ្រើសរើស​ឧបករណ៍ <xliff:g id="COUNT">%1$d</xliff:g>"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(បាន​ដាច់)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"មិនអាចប្ដូរបានទេ។ សូមចុចដើម្បី​ព្យាយាម​ម្ដងទៀត។"</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ផ្គូផ្គង​ឧបករណ៍ថ្មី"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ដើម្បីភ្ជាប់វគ្គនេះ សូមបើកកម្មវិធី។"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"កម្មវិធី​ដែលមិន​ស្គាល់"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"បញ្ឈប់ការភ្ជាប់"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ត្រូវបានបិទ"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"មុខងារ​អាទិភាព"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"រូបកំណត់​ម៉ោងរោទ៍"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"កាមេរ៉ា និង​មីក្រូហ្វូន​ត្រូវបានបិទ"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{ការ​ជូន​ដំណឹង #}other{ការ​ជូនដំណឹង #}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ការផ្សាយ"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"បញ្ឈប់ការផ្សាយ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ប្រសិនបើអ្នក​ផ្សាយ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ឬប្ដូរឧបករណ៍បញ្ចេញសំឡេង ការផ្សាយបច្ចុប្បន្នរបស់អ្នកនឹង​បញ្ឈប់"</string>
     <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..8effb54 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"ಪುನಃ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"ತೆರೆಯಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ತೆರೆಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ತೆರೆಯಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> ಸಾಧನಗಳನ್ನು ಆಯ್ಕೆ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ಡಿಸ್‌ಕನೆಕ್ಟ್ ಆಗಿದೆ)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ಬದಲಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ಹೊಸ ಸಾಧನವನ್ನು ಜೋಡಿಸಿ"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ಈ ಸೆಶನ್ ಕಾಸ್ಟ್ ಮಾಡಲು, ಆ್ಯಪ್ ಅನ್ನು ತೆರೆಯಿರಿ."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ಅಪರಿಚಿತ ಆ್ಯಪ್"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ಬಿತ್ತರಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಿ"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ವೈ-ಫೈ ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ಆದ್ಯತೆ ಮೋಡ್"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ಅಲಾರಾಂ ಹೊಂದಿಸಲಾಗಿದೆ"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ ಆಫ್ ಆಗಿದೆ"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ಅಧಿಸೂಚನೆ}one{# ಅಧಿಸೂಚನೆಗಳು}other{# ಅಧಿಸೂಚನೆಗಳು}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ಪ್ರಸಾರ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನ ಪ್ರಸಾರವನ್ನು ನಿಲ್ಲಿಸಬೇಕೆ?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ನೀವು <xliff:g id="SWITCHAPP">%1$s</xliff:g> ಅನ್ನು ಪ್ರಸಾರ ಮಾಡಿದರೆ ಅಥವಾ ಔಟ್‌ಪುಟ್ ಅನ್ನು ಬದಲಾಯಿಸಿದರೆ, ನಿಮ್ಮ ಪ್ರಸ್ತುತ ಪ್ರಸಾರವು ಸ್ಥಗಿತಗೊಳ್ಳುತ್ತದೆ"</string>
     <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..27fdc37 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"다시 탭하세요."</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"위로 스와이프하여 열기"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"기기를 열려면 잠금 해제 아이콘을 누르세요."</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"얼굴 인식으로 잠금 해제되었습니다. 위로 스와이프하여 여세요."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"기기 <xliff:g id="COUNT">%1$d</xliff:g>대 선택됨"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(연결 끊김)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"전환할 수 없습니다. 다시 시도하려면 탭하세요."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"새 기기와 페어링"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"세션을 전송하려면 앱을 열어 주세요"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"알 수 없는 앱"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"전송 중지"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi를 이용할 수 없습니다."</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"우선순위 모드입니다."</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"알람이 설정되었습니다."</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"카메라 및 마이크가 사용 중지되었습니다."</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{알림 #개}other{알림 #개}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"방송 중"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> 방송을 중지하시겠습니까?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> 앱을 방송하거나 출력을 변경하면 기존 방송이 중단됩니다"</string>
     <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..75d8582 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"Кайра таптап коюңуз"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Ачуу үчүн өйдө сүрүңүз"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Кулпуну ачуу сүрөтчөсүн басыңыз"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Түзмөгүңүздү жүзүңүз менен ачтыңыз. Эми өйдө сүрүп коюңуз."</string>
     <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 +468,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> түзмөк тандалды"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ажыратылды)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Которулбай жатат. Кайталоо үчүн басыңыз."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңы түзмөк кошуу"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Бул сеансты тышкы экранга чыгаруу үчүн колдонмону ачыңыз."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Белгисиз колдонмо"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Тышкы экранга чыгарууну токтотуу"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi жеткиликсиз"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Маанилүү сүйлөшүүлөр режими"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Ойготкуч коюлду"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера жана микрофон өчүк"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# билдирме}other{# билдирме}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Кеңири таратуу"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда кабарлоо токтотулсунбу?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Эгер <xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарласаңыз же аудионун чыгуусун өзгөртсөңүз, учурдагы кабарлоо токтотулат"</string>
     <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..35b85dd 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"ແຕະອີກເທື່ອໜຶ່ງ"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"ປັດຂຶ້ນເພື່ອເປີດ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ກົດໄອຄອນປົດລັອກເພື່ອເປີດ"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"ປົດລັອກດ້ວຍໃບໜ້າແລ້ວ. ປັດຂຶ້ນເພື່ອເປີດ."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"ເລືອກ <xliff:g id="COUNT">%1$d</xliff:g> ອຸປະກອນແລ້ວ"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ຕັດການເຊື່ອມຕໍ່ແລ້ວ)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ບໍ່ສາມາດສະຫຼັບໄດ້. ແຕະເພື່ອລອງໃໝ່."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ຈັບຄູ່ອຸປະກອນໃໝ່"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ເພື່ອສົ່ງສັນຍານເຊດຊັນນີ້, ກະລຸນາເປີດແອັບ."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ແອັບທີ່ບໍ່ຮູ້ຈັກ"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ຢຸດການສົ່ງສັນຍານ"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ບໍ່ສາມາດໃຊ້ Wi‑Fi ໄດ້"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ໂໝດຄວາມສຳຄັນ"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ຕັ້ງໂມງປຸກແລ້ວ"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ປິດກ້ອງຖ່າຍຮູບ ແລະ ໄມແລ້ວ"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ການແຈ້ງເຕືອນ}other{# ການແຈ້ງເຕືອນ}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ກຳລັງອອກອາກາດ"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"ຢຸດການອອກອາກາດ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ຫາກທ່ານອອກອາກາດ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ຫຼື ປ່ຽນເອົ້າພຸດ, ການອອກອາກາດປັດຈຸບັນຂອງທ່ານຈະຢຸດ"</string>
     <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..db3887e 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Atrakinta pagal veidą. Atidarykite perbraukę aukštyn."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Pasirinkta įrenginių: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(atjungta)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nepavyko perjungti. Bandykite vėl palietę."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Naujo įrenginio susiejimas"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Jei norite perduoti šį seansą, atidarykite programą."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nežinoma programa"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Sustabdyti perdavimą"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"„Wi‑Fi“ ryšys nepasiekiamas"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteto režimas"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signalas nustatytas"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Vaizdo kamera ir mikrofonas išjungti"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# pranešimas}one{# pranešimas}few{# pranešimai}many{# pranešimo}other{# pranešimų}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transliavimas"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Sustabdyti „<xliff:g id="APP_NAME">%1$s</xliff:g>“ transliaciją?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jei transliuosite „<xliff:g id="SWITCHAPP">%1$s</xliff:g>“ arba pakeisite išvestį, dabartinė transliacija bus sustabdyta"</string>
     <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..6c1ae36 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Ierīce atbloķēta ar seju. Velciet augšup, lai atvērtu."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Atlasītas vairākas ierīces (kopā <xliff:g id="COUNT">%1$d</xliff:g>)"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(savienojums pārtraukts)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nevar pārslēgt. Pieskarieties, lai mēģinātu vēlreiz."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Savienošana pārī ar jaunu ierīci"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Lai apraidītu šo sesiju, lūdzu, atveriet lietotni."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nezināma lietotne"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Apturēt apraidi"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nav pieejams"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritātes režīms"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signāls ir iestatīts"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera un mikrofons ir izslēgti"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# paziņojums}zero{# paziņojumu}one{# paziņojums}other{# paziņojumi}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Notiek apraidīšana"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vai apturēt lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> apraidīšanu?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ja sāksiet lietotnes <xliff:g id="SWITCHAPP">%1$s</xliff:g> apraidīšanu vai mainīsiet izvadi, pašreizējā apraide tiks apturēta"</string>
     <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..a612167 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"Допрете повторно"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Повлечете за да отворите"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Притиснете ја иконата за отклучување за да отворите"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Отклучено со лице. Повлечете за да отворите."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Избрани се <xliff:g id="COUNT">%1$d</xliff:g> уреди"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(врската е прекината)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не се префрла. Допрете и обидете се пак."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Спарете нов уред"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"За да ја емитувате сесијава, отворете ја апликацијата."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Непозната апликација"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Сопри со емитување"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi е недостапна"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетен режим"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Алармот е наместен"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камерата и микрофонот се исклучени"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# известување}one{# известување}other{# известувања}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Емитување"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Да се прекине емитувањето на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако емитувате на <xliff:g id="SWITCHAPP">%1$s</xliff:g> или го промените излезот, тековното емитување ќе запре"</string>
     <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..5b48a37 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"വീണ്ടും ടാപ്പ് ചെയ്യുക"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"തുറക്കാൻ മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"തുറക്കാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"മുഖം വഴി അൺലോക്കുചെയ്തു. മുകളിലേക്ക് സ്വൈപ്പുചെയ്ത് തുറക്കൂ."</string>
     <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 +404,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> ഉപകരണങ്ങൾ തിരഞ്ഞെടുത്തു"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(വിച്ഛേദിച്ചു)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"മാറാനാകുന്നില്ല. വീണ്ടും ശ്രമിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"പുതിയ ഉപകരണവുമായി ജോടിയാക്കുക"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ഈ സെഷൻ കാസ്റ്റ് ചെയ്യാൻ, ആപ്പ് തുറക്കുക."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"അജ്ഞാതമായ ആപ്പ്"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"കാസ്റ്റ് ചെയ്യുന്നത് നിർത്തുക"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"വൈഫൈ ലഭ്യമല്ല"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"മുൻഗണനാ മോഡ്"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"അലാറം സജ്ജീകരിച്ചു"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ക്യാമറയും മൈക്കും ഓഫാണ്"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# അറിയിപ്പ്}other{# അറിയിപ്പുകൾ}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"പ്രക്ഷേപണം ചെയ്യുന്നു"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ബ്രോഡ്‌കാസ്റ്റ് ചെയ്യുന്നത് അവസാനിപ്പിക്കണോ?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"നിങ്ങൾ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ബ്രോഡ്‌കാസ്റ്റ് ചെയ്യുകയോ ഔട്ട്പുട്ട് മാറ്റുകയോ ചെയ്താൽ നിങ്ങളുടെ നിലവിലുള്ള ബ്രോഡ്‌കാസ്റ്റ് അവസാനിക്കും"</string>
     <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..68fe4c5 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"Дaхин товшино уу"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Нээхийн тулд дээш шударна уу"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Нээхийн тулд түгжээг тайлах дүрс тэмдэг дээр дараарай"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Царайгаар түгжээг тайлсан. Нээхийн тулд дээш шударна уу."</string>
     <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 +704,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> төхөөрөмж сонгосон"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(салсан)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Сэлгэх боломжгүй. Дахин оролдохын тулд товшино уу."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Шинэ төхөөрөмж хослуулах"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Энэ үйл явдлыг дамжуулахын тулд аппыг нээнэ үү."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Үл мэдэгдэх апп"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Дамжуулахыг зогсоох"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi боломжгүй"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Чухал горим"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Сэрүүлгийг тохируулсан"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камер болон микрофон унтраалттай байна"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# мэдэгдэл}other{# мэдэгдэл}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Нэвтрүүлэлт"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г нэвтрүүлэхээ зогсоох уу?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Хэрэв та <xliff:g id="SWITCHAPP">%1$s</xliff:g>-г нэвтрүүлсэн эсвэл гаралтыг өөрчилсөн бол таны одоогийн нэвтрүүлэлтийг зогсооно"</string>
     <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..be8933f 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"पुन्हा टॅप करा"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"उघडण्यासाठी वर स्वाइप करा"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"उघडण्यासाठी अनलॉक करा आयकन दाबा"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"चेहऱ्याने अनलॉक केले आहे. उघडण्यासाठी वर स्वाइप करा."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> डिव्हाइस निवडली आहेत"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(डिस्कनेक्ट केलेले)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"स्विच करू शकत नाही. पुन्हा प्रयत्न करण्यासाठी टॅप करा."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नवीन डिव्हाइससोबत पेअर करा"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"हे सेशन कास्ट करण्यासाठी, कृपया ॲप उघडा."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अज्ञात अ‍ॅप"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"कास्ट करणे थांबवा"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"वाय-फाय उपलब्ध नाही"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"प्राधान्य मोड"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट केला"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"कॅमेरा आणि माइक बंद आहेत"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# सूचना}other{# सूचना}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ब्रॉडकास्ट करत आहे"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> चे प्रसारण थांबवायचे आहे का?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"तुम्ही <xliff:g id="SWITCHAPP">%1$s</xliff:g> चे प्रसारण केल्यास किंवा आउटपुट बदलल्यास, तुमचे सध्याचे प्रसारण बंद होईल"</string>
     <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..3989e5d 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Dibuka kunci dengan wajah. Leret ke atas untuk buka."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> peranti dipilih"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(diputuskan sambungan)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Tidak dapat menukar. Ketik untuk mencuba lagi."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Gandingkan peranti baharu"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Untuk menghantar sesi ini, sila buka apl."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Apl yang tidak diketahui"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Berhenti menghantar"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi dimatikan"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mod keutamaan"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Penggera ditetapkan"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dan mikrofon dimatikan"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# pemberitahuan}other{# pemberitahuan}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Menyiarkan"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hentikan siaran <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jika anda siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g> atau tukarkan output, siaran semasa anda akan berhenti"</string>
     <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..5bbe429 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"ထပ်တို့ပါ"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"ဖွင့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ဖွင့်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ဖွင့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ။"</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"စက်ပစ္စည်း <xliff:g id="COUNT">%1$d</xliff:g> ခုကို ရွေးချယ်ထားသည်"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ချိတ်ဆက်မှု မရှိပါ)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ပြောင်း၍ မရပါ။ ပြန်စမ်းကြည့်ရန် တို့ပါ။"</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"စက်အသစ် တွဲချိတ်ရန်"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"အက်ပ်ဖွင့်ပြီး ဤစက်ရှင်ကို ကာစ်လုပ်နိုင်သည်။"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"အမည်မသိ အက်ပ်"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ကာစ် ရပ်ရန်"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi မရပါ"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ဦးစားပေးမုဒ်"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"နိုးစက် သတ်မှတ်ထားသည်"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ကင်မရာနှင့် မိုက် ပိတ်ထားသည်"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{အကြောင်းကြားချက် # ခု}other{အကြောင်းကြားချက် # ခု}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ထုတ်လွှင့်ခြင်း"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ထုတ်လွှင့်ခြင်းကို ရပ်မလား။"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ကို ထုတ်လွှင့်သောအခါ (သို့) အထွက်ကို ပြောင်းသောအခါ သင့်လက်ရှိထုတ်လွှင့်ခြင်း ရပ်သွားမည်"</string>
     <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..c18d690 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,8 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Låst opp med ansiktet. Sveip opp for å åpne."</string>
+    <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 +475,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> enheter er valgt"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(frakoblet)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan ikke bytte. Trykk for å prøve igjen."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Koble til en ny enhet"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"For å caste denne økten, åpne appen."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ukjent app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stopp castingen"</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>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi er utilgjengelig"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteringsmodus"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmen er stilt inn"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera og mikrofon er av"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# varsel}other{# varsler}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Kringkaster"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vil du stoppe kringkastingen av <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Hvis du kringkaster <xliff:g id="SWITCHAPP">%1$s</xliff:g> eller endrer utgangen, stopper den nåværende kringkastingen din"</string>
     <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..e9c843f 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"फेरि ट्याप गर्नुहोस्"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"खोल्न माथितिर स्वाइप गर्नुहोस्"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"खोल्न अनलक आइकनमा थिच्नुहोस्"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"अनुहार प्रयोग गरी अनलक गरियो। खोल्न माथितिर स्वाइप गर्नुहोस्"</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> वटा यन्त्र चयन गरिए"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(डिस्कनेक्ट गरिएको छ)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"बदल्न सकिएन। फेरि प्रयास गर्न ट्याप गर्नुहोस्।"</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नयाँ डिभाइस कनेक्ट गर्नुहोस्"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"यो सत्र कास्ट गर्न चाहनुहुन्छ भने कृपया एप खोल्नुहोस्।"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अज्ञात एप"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"कास्ट गर्न छाड्नुहोस्"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi उपलब्ध छैन"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"प्राथमिकता मोड"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट गरिएको छ"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"क्यामेरा र माइक अफ छन्"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# वटा सूचना}other{# वटा सूचनाहरू}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"प्रसारण गरिँदै छ"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ब्रोडकास्ट गर्न छाड्ने हो?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"तपाईंले <xliff:g id="SWITCHAPP">%1$s</xliff:g> ब्रोडकास्ट गर्नुभयो वा आउटपुट परिवर्तन गर्नुभयो भने तपाईंको हालको ब्रोडकास्ट रोकिने छ"</string>
     <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-night/styles.xml b/packages/SystemUI/res/values-night/styles.xml
index cf49728..6f87169 100644
--- a/packages/SystemUI/res/values-night/styles.xml
+++ b/packages/SystemUI/res/values-night/styles.xml
@@ -44,7 +44,6 @@
         <item name="android:windowLightStatusBar">false</item>
         <item name="android:windowLightNavigationBar">false</item>
         <item name="android:navigationBarColor">?android:attr/colorBackgroundFloating</item>
-        <item name="android:textColorSecondary">?android:attr/textColorPrimaryInverse</item>
     </style>
 
     <style name="FloatingOverlay" parent="@android:style/Theme.DeviceDefault.DayNight">
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 9501ddf..2cdafa5 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Ontgrendeld via gezicht. Swipe omhoog om te openen."</string>
     <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 +372,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> apparaten geselecteerd"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(verbinding verbroken)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan niet schakelen. Tik om het opnieuw te proberen."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Nieuw apparaat koppelen"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Als je deze sessie wilt casten, open je de app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Onbekende app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Casten stoppen"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wifi niet beschikbaar"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteitsmodus"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wekker gezet"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera en microfoon staan uit"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# melding}other{# meldingen}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Uitzending"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Uitzending van <xliff:g id="APP_NAME">%1$s</xliff:g> stopzetten?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Als je <xliff:g id="SWITCHAPP">%1$s</xliff:g> uitzendt of de uitvoer wijzigt, wordt je huidige uitzending gestopt"</string>
     <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..aae1439 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"ପୁଣି ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"ଖୋଲିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ଖୋଲିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଖୋଲିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ କରନ୍ତୁ।"</string>
     <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 +620,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 +652,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,14 +824,15 @@
     <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>
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g>ଟି ଡିଭାଇସ୍ ଚୟନ କରାଯାଇଛି"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ବିଚ୍ଛିନ୍ନ କରାଯାଇଛି)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ସ୍ୱିଚ କରାଯାଇପାରିବ ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ନୂଆ ଡିଭାଇସକୁ ପେୟାର୍ କରନ୍ତୁ"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ଏହି ସେସନକୁ କାଷ୍ଟ କରିବା ପାଇଁ, ଦୟାକରି ଆପ ଖୋଲନ୍ତୁ।"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ଅଜଣା ଆପ"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"କାଷ୍ଟ କରିବା ବନ୍ଦ କରନ୍ତୁ"</string>
@@ -938,19 +937,28 @@
     <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>
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ୱାଇ-ଫାଇ ଉପଲବ୍ଧ ନାହିଁ"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ପ୍ରାଥମିକତା ମୋଡ"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ଆଲାରାମ ସେଟ"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"କ୍ୟାମେରା ଏବଂ ମାଇକ ବନ୍ଦ ଅଛି"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{#ଟି ବିଜ୍ଞପ୍ତି}other{#ଟି ବିଜ୍ଞପ୍ତି}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ବ୍ରଡକାଷ୍ଟ କରୁଛି"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରିବା ବନ୍ଦ କରିବେ?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ଯଦି ଆପଣ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରନ୍ତି କିମ୍ବା ଆଉଟପୁଟ ବଦଳାନ୍ତି, ତେବେ ଆପଣଙ୍କ ବର୍ତ୍ତମାନର ବ୍ରଡକାଷ୍ଟ ବନ୍ଦ ହୋଇଯିବ"</string>
     <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..4492796 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"ਦੁਬਾਰਾ ਟੈਪ ਕਰੋ"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"ਖੋਲ੍ਹਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ਖੋਲ੍ਹਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਖੋਲ੍ਹਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ।"</string>
     <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 +363,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> ਡੀਵਾਈਸਾਂ ਨੂੰ ਚੁਣਿਆ ਗਿਆ"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ਡਿਸਕਨੈਕਟ ਹੈ)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ਨਵਾਂ ਡੀਵਾਈਸ ਜੋੜਾਬੱਧ ਕਰੋ"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ਇਸ ਸੈਸ਼ਨ ਨੂੰ ਕਾਸਟ ਕਰਨ ਲਈ, ਕਿਰਪਾ ਕਰਕੇ ਐਪ ਖੋਲ੍ਹੋ।"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ਅਗਿਆਤ ਐਪ"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ਕਾਸਟ ਕਰਨਾ ਬੰਦ ਕਰੋ"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ਵਾਈ-ਫਾਈ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ਤਰਜੀਹੀ ਮੋਡ"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ਅਲਾਰਮ ਸੈੱਟ ਹੈ"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ਕੈਮਰਾ ਅਤੇ ਮਾਈਕ ਬੰਦ ਹਨ"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ਸੂਚਨਾ}one{# ਸੂਚਨਾ}other{# ਸੂਚਨਾਵਾਂ}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ਪ੍ਰਸਾਰਨ"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਦੇ ਪ੍ਰਸਾਰਨ ਨੂੰ ਰੋਕਣਾ ਹੈ?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ਜੇ ਤੁਸੀਂ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ਦਾ ਪ੍ਰਸਾਰਨ ਕਰਦੇ ਹੋ ਜਾਂ ਆਊਟਪੁੱਟ ਬਦਲਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਪ੍ਰਸਾਰਨ ਰੁਕ ਜਾਵੇਗਾ"</string>
     <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..280000d 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Odblokowano skanem twarzy. Przesuń w górę, aby otworzyć."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Wybrane urządzenia: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(odłączono)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nie można przełączyć. Spróbuj ponownie."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sparuj nowe urządzenie"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Aby przesłać tę sesję, otwórz aplikację."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nieznana aplikacja"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zatrzymaj przesyłanie"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Sieć Wi‑Fi niedostępna"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Tryb priorytetowy"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm ustawiony"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Aparat i mikrofon są wyłączone"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# powiadomienie}few{# powiadomienia}many{# powiadomień}other{# powiadomienia}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmisja"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zatrzymaj transmisję aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jeśli transmitujesz aplikację <xliff:g id="SWITCHAPP">%1$s</xliff:g> lub zmieniasz dane wyjściowe, Twoja obecna transmisja zostanie zakończona"</string>
     <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..d93e141 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Desbloqueado pelo rosto. Deslize para cima para abrir."</string>
     <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 +372,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> dispositivos selecionados"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(sem conexão)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Não foi possível mudar. Toque para tentar novamente."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parear novo dispositivo"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Abra o app para transmitir esta sessão."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecido"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Parar transmissão"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi indisponível"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo de prioridade"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmera e o microfone estão desativados"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}one{# notificação}other{# notificações}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmitindo"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Interromper a transmissão do app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se você transmitir o app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou mudar a saída, a transmissão atual será interrompida"</string>
     <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..d9e9c23 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Desbloqueado com o rosto. Deslize para cima para abrir."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> dispositivos selecionados"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desligado)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Não é possível mudar. Toque para tentar novamente."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sincronize o novo dispositivo"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para transmitir esta sessão, abra a app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecida"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Parar transmissão"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi indisponível"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo Prioridade"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmara e o microfone estão desativados"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}other{# notificações}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"A transmitir"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Interromper a transmissão da app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se transmitir a app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou alterar a saída, a sua transmissão atual é interrompida"</string>
     <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..d93e141 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Desbloqueado pelo rosto. Deslize para cima para abrir."</string>
     <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 +372,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> dispositivos selecionados"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(sem conexão)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Não foi possível mudar. Toque para tentar novamente."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parear novo dispositivo"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Abra o app para transmitir esta sessão."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecido"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Parar transmissão"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi indisponível"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo de prioridade"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmera e o microfone estão desativados"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}one{# notificação}other{# notificações}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmitindo"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Interromper a transmissão do app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se você transmitir o app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou mudar a saída, a transmissão atual será interrompida"</string>
     <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..3d7f17b 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"S-a deblocat folosind fața. Glisați în sus și deschideți."</string>
     <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 +372,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"S-au selectat <xliff:g id="COUNT">%1$d</xliff:g> dispozitive"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(deconectat)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nu se poate comuta. Atingeți pentru a încerca din nou."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Asociați un nou dispozitiv"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pentru a proiecta această sesiune, deschideți aplicația."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicație necunoscută"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Nu mai proiectați"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi indisponibil"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modul Prioritate"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmă setată"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera și microfonul sunt dezactivate"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificare}few{# notificări}other{# de notificări}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Se difuzează"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Opriți difuzarea <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Dacă difuzați <xliff:g id="SWITCHAPP">%1$s</xliff:g> sau schimbați rezultatul, difuzarea actuală se va opri"</string>
     <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..75dd819 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"Нажмите ещё раз"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Проведите вверх, чтобы открыть"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Нажмите на значок разблокировки."</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Сканирование выполнено. Чтобы открыть, проведите вверх."</string>
     <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 +372,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Выбрано устройств: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(нет подключения)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не удается переключиться. Нажмите, чтобы повторить попытку."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Подключить новое устройство"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Чтобы начать трансляцию сеанса, откройте приложение"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Неизвестное приложение"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Остановить трансляцию"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Сеть Wi‑Fi недоступна"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Режим приоритета"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будильник установлен"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера и микрофон отключены"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# уведомление}one{# уведомление}few{# уведомления}many{# уведомлений}other{# уведомления}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Трансляция"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Остановить трансляцию \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Если вы начнете транслировать \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\" или смените целевое устройство, текущая трансляция прервется."</string>
     <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..763fc59 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"නැවත තට්ටු කරන්න"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"විවෘත කිරීමට ස්වයිප් කරන්න"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"විවෘත කිරීමට අගුලු හැරීමේ නිරූපකය ඔබන්න"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"මුහුණ මගින් අගුලු හරින ලදි. විවෘත කිරීමට ස්වයිප් කරන්න."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"උපාංග <xliff:g id="COUNT">%1$d</xliff:g>ක් තෝරන ලදී"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(විසන්ධි විය)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"මාරු කිරීමට නොහැකිය. නැවත උත්සාහ කිරීමට තට්ටු කරන්න."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"නව උපාංගය යුගල කරන්න"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"මෙම සැසිය විකාශය කිරීමට, කරුණාකර යෙදුම විවෘත කරන්න."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"නොදන්නා යෙදුම"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"විකාශය නවතන්න"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ලබා ගත නොහැකිය"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ප්‍රමුඛතා ප්‍රකාරය"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"සීනුව සකසන ලදි"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"කැමරාව සහ මයික් ක්‍රියාවිරහිතයි"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{දැනුම්දීම් #ක්}one{දැනුම්දීම් #ක්}other{දැනුම්දීම් #ක්}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"විකාශනය කරමින්"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> විකාශනය කිරීම නවත්වන්නද?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ඔබ <xliff:g id="SWITCHAPP">%1$s</xliff:g> විකාශනය කළහොත් හෝ ප්‍රතිදානය වෙනස් කළහොත්, ඔබගේ වත්මන් විකාශනය නවතිනු ඇත."</string>
     <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..86252ef 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Odomknuté tvárou. Otvoríte potiahnutím nahor."</string>
     <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 +372,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Počet vybraných zariadení: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(odpojené)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nedá sa prepnúť. Zopakujte klepnutím."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Spárovať nové zariadenie"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ak chcete túto reláciu prenášať, otvorte aplikáciu."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznáma aplikácia"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zastaviť prenos"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nie je k dispozícii"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Režim priority"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Budík je nastavený"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera a mikrofón sú vypnuté"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# upozornenie}few{# upozornenia}many{# notifications}other{# upozornení}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Vysiela"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Chcete zastaviť vysielanie aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ak vysielate aplikáciu <xliff:g id="SWITCHAPP">%1$s</xliff:g> alebo zmeníte výstup, aktuálne vysielanie bude zastavené"</string>
     <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..e6798c7 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Odklenjeno z obrazom. Povlecite navzgor, da odprete."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Izbranih je toliko naprav: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(povezava je prekinjena)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Preklop ni mogoč. Če želite poskusiti znova, se dotaknite."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Seznanitev nove naprave"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Če želite predvajati to sejo, odprite aplikacijo."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznana aplikacija"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Ustavi predvajanje"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ni na voljo."</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prednostni način"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je nastavljen."</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparat in mikrofon sta izklopljena."</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obvestilo}one{# obvestilo}two{# obvestili}few{# obvestila}other{# obvestil}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Oddajanje"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Želite ustaviti oddajanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Če oddajate aplikacijo <xliff:g id="SWITCHAPP">%1$s</xliff:g> ali spremenite izhod, bo trenutno oddajanje ustavljeno."</string>
     <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..11277c3 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"U shkyç me fytyrë. Rrëshqit shpejt lart për ta hapur."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> pajisje të zgjedhura"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(shkëputur)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nuk mund të ndërrohet. Trokit për të provuar përsëri."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Çifto pajisjen e re"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Hap aplikacionin për të transmetuar këtë seancë."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikacion i panjohur"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Ndalo transmetimin"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nuk ofrohet"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modaliteti \"Me përparësi\""</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmi është caktuar"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dhe mikrofoni janë joaktivë"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# njoftim}other{# njoftime}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Po transmeton"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Të ndalohet transmetimi i <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Nëse transmeton <xliff:g id="SWITCHAPP">%1$s</xliff:g> ose ndryshon daljen, transmetimi yt aktual do të ndalojë"</string>
     <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..7e28dbe 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"Додирните поново"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Превуците нагоре да бисте отворили"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Притисните икону откључавања да бисте отворили."</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Откључано је лицем. Превуците нагоре да бисте отворили."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Изабраних уређаја: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(веза је прекинута)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Пребацивање није успело. Пробајте поново."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Упари нови уређај"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Да бисте пребацивали ову сесију, отворите апликацију."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Непозната апликација"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Заустави пребацивање"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi није доступан"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетни режим"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Аларм је подешен"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера и микрофон су искључени"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# обавештење}one{# обавештење}few{# обавештења}other{# обавештења}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Емитовање"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Желите да зауставите емитовање апликације <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако емитујете апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените излаз, актуелно емитовање ће се зауставити"</string>
     <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..01d00b1 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Upplåst med ansiktslås. Öppna genom att svepa uppåt."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> enheter har valts"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(frånkopplad)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Misslyckat byte. Tryck och försök igen."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parkoppla en ny enhet"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Öppna appen om du vill casta den här sessionen."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Okänd app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Sluta casta"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wifi är inte tillgängligt"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetsläge"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmet är aktiverat"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kameran och mikrofonen är avstängda"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# avisering}other{# aviseringar}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Sänder"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vill du sluta sända från <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Om en utsändning från <xliff:g id="SWITCHAPP">%1$s</xliff:g> pågår eller om du byter ljudutgång avbryts den nuvarande utsändningen"</string>
     <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..2a654eb 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Imefunguliwa kwa kutumia uso wako. Telezesha kidole juu ili ufungue."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Umechagua vifaa <xliff:g id="COUNT">%1$d</xliff:g>"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(imetenganishwa)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Imeshindwa kubadilisha. Gusa ili ujaribu tena."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Oanisha kifaa kipya"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ili utume kipindi hiki, tafadhali fungua programu."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Programu isiyojulikana"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Acha kutuma"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi haipatikani"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Hali ya kipaumbele"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Kengele imewekwa"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera na maikrofoni zimezimwa"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{Arifa #}other{Arifa #}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Inaarifu"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Ungependa kusimamisha utangazaji kwenye <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ikiwa unatangaza kwenye <xliff:g id="SWITCHAPP">%1$s</xliff:g> au unabadilisha maudhui, tangazo lako la sasa litasimamishwa"</string>
     <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..c9b057f 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"மீண்டும் தட்டவும்"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"திறப்பதற்கு மேல் நோக்கி ஸ்வைப் செய்யவும்"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"திறக்க, அன்லாக் ஐகானை அழுத்தவும்"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"முகத்தால் அன்லாக் செய்யப்பட்டது திறக்க மேல்நோக்கி ஸ்வைப்செய்க"</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> சாதனங்கள் தேர்ந்தெடுக்கப்பட்டுள்ளன"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(துண்டிக்கப்பட்டது)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"இணைக்க முடியவில்லை. மீண்டும் முயல தட்டவும்."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"புதிய சாதனத்தை இணைத்தல்"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"இந்த அமர்வை அலைபரப்ப ஆப்ஸைத் திறங்கள்."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"அறியப்படாத ஆப்ஸ்"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"அலைபரப்புவதை நிறுத்து"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"வைஃபை கிடைக்கவில்லை"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"முன்னுரிமைப் பயன்முறை"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"அலாரம் அமைக்கப்பட்டுள்ளது"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"கேமராவும் மைக்கும் ஆஃப் செய்யப்பட்டுள்ளன"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# அறிவிப்பு}other{# அறிவிப்புகள்}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ஒலிபரப்புதல்"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் ஒலிபரப்பப்படுவதை நிறுத்தவா?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"நீங்கள் <xliff:g id="SWITCHAPP">%1$s</xliff:g> ஆப்ஸை ஒலிபரப்பினாலோ அவுட்புட்டை மாற்றினாலோ உங்களின் தற்போதைய ஒலிபரப்பு நிறுத்தப்படும்"</string>
     <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..bc7b79d 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -49,8 +49,8 @@
     <string name="always_use_accessory" msgid="1977225429341838444">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> కనెక్ట్ అయి ఉన్న ఎల్లప్పుడూ <xliff:g id="APPLICATION">%1$s</xliff:g>ని తెరవండి"</string>
     <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_always" msgid="4003121804294739548">"ఈ కంప్యూటర్ నుండి ఎల్లప్పుడూ అనుమతించండి"</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>
@@ -59,8 +59,8 @@
     <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"ప్రస్తుత భాషను అలా ఉంచండి"</string>
     <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_always" msgid="2968383799517975155">"ఈ నెట్‌వర్క్ నుండి ఎల్లప్పుడూ అనుమతించండి"</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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"మళ్లీ ట్యాప్ చేయండి"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"తెరవడానికి, పైకి స్వైప్ చేయండి"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"తెరవడానికి అన్‌లాక్ చిహ్నాన్ని నొక్కండి"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"ముఖం ద్వారా అన్‌లాక్ అయింది. తెరవడానికి, పైకి స్వైప్ చేయండి."</string>
     <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>
@@ -353,7 +351,7 @@
     <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{ఒక యూజర్‌ను మాత్రమే క్రియేట్ చేయవచ్చు.}other{మీరు గరిష్టంగా # మంది యూజర్‌లను జోడించవచ్చు.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"వినియోగదారుని తీసివేయాలా?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"ఈ వినియోగదారుకు సంబంధించిన అన్ని యాప్‌లు మరియు డేటా తొలగించబడతాయి."</string>
-    <string name="user_remove_user_remove" msgid="8387386066949061256">"తీసివేయి"</string>
+    <string name="user_remove_user_remove" msgid="8387386066949061256">"తీసివేయండి"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"రికార్డ్ చేస్తున్నప్పుడు లేదా ప్రసారం చేస్తున్నప్పుడు, మీ స్క్రీన్‌పై ప్రదర్శించబడిన లేదా మీ పరికరం నుండి ప్లే చేయబడిన సమాచారం మొత్తాన్ని, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> యాక్సెస్ చేయగలుగుతుంది. ఈ సమాచారంలో, పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, ఫోటోలు, మెసేజ్‌లు, మీరు ప్లే చేసే ఆడియో వంటివి ఉంటాయి."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"రికార్డ్ చేస్తున్నప్పుడు లేదా ప్రసారం చేస్తున్నప్పుడు మీ స్క్రీన్‌పై ప్రదర్శించబడిన లేదా మీ పరికరం నుండి ప్లే చేయబడిన సమాచారం మొత్తాన్ని, ఈ ఫంక్షన్‌ను అందిస్తున్న సర్వీస్ యాక్సెస్ చేయగలదు. ఈ సమాచారంలో, పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, ఫోటోలు,  మెసేజ్‌లు, మీరు ప్లే చేసే ఆడియో వంటివి ఉంటాయి."</string>
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"రికార్డ్ చేయడం లేదా ప్రసారం చేయడం ప్రారంభించాలా?"</string>
@@ -480,11 +478,11 @@
     <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>
-    <string name="remove_from_settings" msgid="633775561782209994">"సెట్టింగ్‌ల నుండి తీసివేయి"</string>
+    <string name="remove_from_settings" msgid="633775561782209994">"సెట్టింగ్‌ల నుండి తీసివేయండి"</string>
     <string name="remove_from_settings_prompt" msgid="551565437265615426">"సిస్టమ్ UI ట్యూనర్‌ను సెట్టింగ్‌ల నుండి తీసివేసి, దాని అన్ని లక్షణాలను ఉపయోగించడం ఆపివేయాలా?"</string>
     <string name="enable_bluetooth_title" msgid="866883307336662596">"బ్లూటూత్ ఆన్ చేయాలా?"</string>
     <string name="enable_bluetooth_message" msgid="6740938333772779717">"మీ కీబోర్డ్‌ను మీ టాబ్లెట్‌తో కనెక్ట్ చేయడానికి, మీరు ముందుగా బ్లూటూత్ ఆన్ చేయాలి."</string>
@@ -529,7 +527,7 @@
     <string name="notification_more_settings" msgid="4936228656989201793">"మరిన్ని సెట్టింగ్‌లు"</string>
     <string name="notification_app_settings" msgid="8963648463858039377">"అనుకూలపరచండి"</string>
     <string name="notification_conversation_bubble" msgid="2242180995373949022">"బబుల్‌ను చూపించు"</string>
-    <string name="notification_conversation_unbubble" msgid="6908427185031099868">"బబుల్స్ తీసివేయి"</string>
+    <string name="notification_conversation_unbubble" msgid="6908427185031099868">"బబుల్స్ తీసివేయండి"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"నోటిఫికేషన్ నియంత్రణలు"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"నోటిఫికేషన్ తాత్కాలిక ఆపివేత ఎంపికలు"</string>
@@ -565,7 +563,7 @@
     <string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string>
     <string name="keyboard_key_num_lock" msgid="7209960042043090548">"Num Lock"</string>
     <string name="keyboard_key_numpad_template" msgid="7316338238459991821">"నంబర్ ప్యాడ్ <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="notif_inline_reply_remove_attachment_description" msgid="7954075334095405429">"అటాచ్‌మెంట్‌ను తీసివేయి"</string>
+    <string name="notif_inline_reply_remove_attachment_description" msgid="7954075334095405429">"అటాచ్‌మెంట్‌ను తీసివేయండి"</string>
     <string name="keyboard_shortcut_group_system" msgid="1583416273777875970">"సిస్టమ్"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="7465138628692109907">"హోమ్"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="8628108256824616927">"ఇటీవలివి"</string>
@@ -715,7 +713,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 +748,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>
@@ -767,7 +765,7 @@
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>వ స్థానంలో ఇష్టమైనదిగా గుర్తు పెట్టబడింది"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ఇష్టమైనదిగా పెట్టిన గుర్తు తీసివేయబడింది"</string>
     <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"ఇష్టమైనదిగా గుర్తు పెట్టు"</string>
-    <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ఇష్టమైనదిగా పెట్టిన గుర్తును తీసివేయి"</string>
+    <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ఇష్టమైనదిగా పెట్టిన గుర్తును తీసివేయండి"</string>
     <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g> పొజిషన్‌కు తరలించండి"</string>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"నియంత్రణలు"</string>
     <string name="controls_favorite_subtitle" msgid="6481675111056961083">"త్వరిత సెట్టింగ్‌ల నుండి యాక్సెస్ చేయడానికి కంట్రోల్స్‌ను ఎంచుకోండి"</string>
@@ -821,7 +819,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> పరికరాలు ఎంచుకోబడ్డాయి"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(డిస్కనెక్ట్ అయ్యింది)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"స్విచ్ చేయడం సాధ్యం కాదు. మళ్ళీ ట్రై చేయడానికి ట్యాప్ చేయండి."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"కొత్త పరికరాన్ని పెయిర్ చేయండి"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ఈ సెషన్‌ను ప్రసారం చేయడానికి, దయచేసి యాప్‌ను తెరవండి."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"తెలియని యాప్"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ప్రసారాన్ని ఆపివేయండి"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi అందుబాటులో లేదు"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ముఖ్యమైన ఫైల్స్ మోడ్"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"అలారం సెట్ చేశాను"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"కెమెరా, మైక్ ఆఫ్‌లో ఉన్నాయి"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# నోటిఫికేషన్}other{# నోటిఫికేషన్‌లు}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ప్రసారం చేస్తోంది"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ప్రసారం చేయడాన్ని ఆపివేయాలా?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"మీరు <xliff:g id="SWITCHAPP">%1$s</xliff:g> ప్రసారం చేస్తే లేదా అవుట్‌పుట్‌ను మార్చినట్లయితే, మీ ప్రస్తుత ప్రసారం ఆగిపోతుంది"</string>
     <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..bacb5aa 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"แตะอีกครั้ง"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"เลื่อนขึ้นเพื่อเปิด"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"กดไอคอนปลดล็อกเพื่อเปิด"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"ปลดล็อกด้วยใบหน้าแล้ว ปัดขึ้นเพื่อเปิด"</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"เลือกอุปกรณ์ไว้ <xliff:g id="COUNT">%1$d</xliff:g> รายการ"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ยกเลิกการเชื่อมต่อแล้ว)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"เปลี่ยนไม่ได้ แตะเพื่อลองอีกครั้ง"</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"จับคู่อุปกรณ์ใหม่"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"โปรดเปิดแอปหากต้องการแคสต์เซสชันนี้"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"แอปที่ไม่รู้จัก"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"หยุดแคสต์"</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>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ใช้ Wi‑Fi ไม่ได้"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"โหมดลำดับความสำคัญ"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ตั้งปลุกแล้ว"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"กล้องและไมค์ปิดอยู่"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{การแจ้งเตือน # รายการ}other{การแจ้งเตือน # รายการ}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"กำลังออกอากาศ"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"หยุดการออกอากาศ <xliff:g id="APP_NAME">%1$s</xliff:g> ไหม"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"หากคุณออกอากาศ <xliff:g id="SWITCHAPP">%1$s</xliff:g> หรือเปลี่ยนแปลงเอาต์พุต การออกอากาศในปัจจุบันจะหยุดลง"</string>
     <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..38fbdf8 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Na-unlock gamit ang mukha. Mag-swipe pataas para buksan."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> (na) device ang napili"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(nadiskonekta)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Hindi makalipat. I-tap para subukan ulit."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Magpares ng bagong device"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para ma-cast ang session na ito, buksan ang app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Hindi kilalang app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Ihinto ang pag-cast"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Hindi available ang Wi‑Fi"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Nakatakda ang alarm"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Naka-off ang camera at mikropono"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}other{# na notification}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Nagbo-broadcast"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Ihinto ang pag-broadcast ng <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Kung magbo-broadcast ka ng <xliff:g id="SWITCHAPP">%1$s</xliff:g> o babaguhin mo ang output, hihinto ang iyong kasalukuyang broadcast"</string>
     <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..8556fc8 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Cihazın kilidini yüzünüzle açtınız. Açmak için yukarı kaydırın."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> cihaz seçildi"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(bağlantı kesildi)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Geçiş yapılamıyor. Tekrar denemek için dokunun."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yeni cihaz eşle"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu oturumu yayınlamak için lütfen uygulamayı açın."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Bilinmeyen uygulama"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Yayını durdur"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Kablosuz kullanılamıyor"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Öncelik modu"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm kuruldu"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera ve mikrofon kapalı"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# bildirim}other{# bildirim}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Yayınlama"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasında anons durdurulsun mu?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uygulamasında anons yapar veya çıkışı değiştirirseniz mevcut anonsunuz duraklatılır"</string>
     <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..357a78b 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"Натисніть знову"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Проведіть пальцем угору, щоб відкрити"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Щоб відкрити, натисніть значок розблокування."</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Розблоковано (фейсконтроль). Відкрити: проведіть угору."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Вибрано пристроїв: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(від’єднано)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не вдалося змінити підключення. Натисніть, щоб повторити спробу."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Підключити новий пристрій"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Щоб транслювати цей сеанс, відкрийте додаток."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Невідомий додаток"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Припинити трансляцію"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Мережа Wi-Fi недоступна"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Режим пріоритету"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будильник установлено"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камеру й мікрофон вимкнено"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# сповіщення}one{# сповіщення}few{# сповіщення}many{# сповіщень}other{# сповіщення}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Трансляція"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Зупинити трансляцію з додатка <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Якщо ви зміните додаток (<xliff:g id="SWITCHAPP">%1$s</xliff:g>) або аудіовихід, поточну трансляцію буде припинено"</string>
     <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..09b23a3 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"دوبارہ تھپتھپائیں"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"کھولنے کے لیے اوپر سوائپ کريں"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"کھولنے کیلئے انلاک آئیکن دبائیں"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"چہرے سے غیر مقفل کیا گیا۔ کھولنے کے لیے اوپر سوائپ کريں۔"</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> آلات منتخب کیے گئے"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(غیر منسلک ہے)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"سوئچ نہیں کر سکتے۔ دوبارہ کوشش کرنے کے لیے تھپتھپائیں۔"</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"نئے آلہ کا جوڑا بنائیں"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"اس سیشن کو کاسٹ کرنے کیلئے، براہ کرم ایپ کھولیں۔"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"نامعلوم ایپ"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"کاسٹ کرنا بند کریں"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‏Wi-Fi دستیاب نہیں ہے"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ترجیحی وضع"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"الارم سیٹ ہوگیا"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"کیمرا اور مائیک آف ہیں"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# اطلاع}other{# اطلاعات}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"نشریات"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> براڈکاسٹنگ روکیں؟"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"اگر آپ <xliff:g id="SWITCHAPP">%1$s</xliff:g> براڈکاسٹ کرتے ہیں یا آؤٹ پٹ کو تبدیل کرتے ہیں تو آپ کا موجودہ براڈکاسٹ رک جائے گا"</string>
     <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..63e5c7f 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Yuz bilan ochildi. Ochish uchun tepaga suring."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> ta qurilma tanlandi"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(uzildi)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Xatolik. Qayta urinish uchun bosing."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yangi qurilmani juftlash"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu seansni translatsiya qilish uchun ilovani oching."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Notanish ilova"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Toʻxtatish"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ishlamayapti"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Imtiyozli rejim"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signal oʻrnatildi"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera va mikrofon yoqilmagan"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ta bildirishnoma}other{# ta bildirishnoma}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Signal uzatish"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga translatsiya toʻxtatilsinmi?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Agar <xliff:g id="SWITCHAPP">%1$s</xliff:g> ilovasiga translatsiya qilsangiz yoki ovoz chiqishini oʻzgartirsangiz, joriy translatsiya toʻxtab qoladi"</string>
     <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..48d1bba 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Đã mở khoá bằng khuôn mặt. Vuốt lên để mở"</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Đã chọn <xliff:g id="COUNT">%1$d</xliff:g> thiết bị"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(đã ngắt kết nối)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Không thể chuyển đổi. Hãy nhấn để thử lại."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Ghép nối thiết bị mới"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Vui lòng mở ứng dụng để truyền phiên này."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ứng dụng không xác định"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Dừng truyền"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Không có Wi‑Fi"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Chế độ ưu tiên"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Đã đặt chuông báo"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Máy ảnh và micrô đang tắt"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# thông báo}other{# thông báo}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Phát sóng"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Dừng phát <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Nếu bạn phát <xliff:g id="SWITCHAPP">%1$s</xliff:g> hoặc thay đổi đầu ra, phiên truyền phát hiện tại sẽ dừng"</string>
     <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..fe8aa30 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"请再点按一次"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"向上滑动即可打开"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"按下解锁图标即可打开"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"已通过面孔识别解锁。向上滑动即可打开。"</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"已选择 <xliff:g id="COUNT">%1$d</xliff:g> 个设备"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(已断开连接)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"无法切换。点按即可重试。"</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"与新设备配对"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如需投射此会话,请打开相关应用。"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"未知应用"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"停止投射"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WLAN 已关闭"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"优先模式"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"闹钟已设置"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"摄像头和麦克风已关闭"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 条通知}other{# 条通知}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"正在广播"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止广播“<xliff:g id="APP_NAME">%1$s</xliff:g>”的内容吗?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如果广播“<xliff:g id="SWITCHAPP">%1$s</xliff:g>”的内容或更改输出来源,当前的广播就会停止"</string>
     <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..0cd35b1 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"再次輕按"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"按解鎖圖示即可開啟"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"已使用面孔解鎖,向上滑動即可開啟。"</string>
     <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 +372,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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"已選取 <xliff:g id="COUNT">%1$d</xliff:g> 部裝置"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(已中斷連線)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"無法切換,輕按即可重試。"</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如要投放此工作階段,請開啟應用程式。"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明應用程式"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"停止投放"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi 已關閉"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"優先模式"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"已設定鬧鐘"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"相機和麥克風已關閉"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 則通知}other{# 則通知}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"廣播"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止廣播「<xliff:g id="APP_NAME">%1$s</xliff:g>」的內容嗎?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如要廣播「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容或變更輸出來源,系統就會停止廣播目前的內容"</string>
     <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..dc2faf0 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,7 @@
     <string name="tap_again" msgid="1315420114387908655">"再輕觸一次"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"按下「解鎖」圖示即可開啟"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"你已用自己的臉解鎖裝置,向上滑動即可開啟。"</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"已選取 <xliff:g id="COUNT">%1$d</xliff:g> 部裝置"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(連線中斷)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"無法切換,輕觸即可重試。"</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如要投放這個工作階段,請開啟應用程式。"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明的應用程式"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"停止投放"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi 已關閉"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"優先模式"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"鬧鐘設定成功"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"已關閉相機和麥克風"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 則通知}other{# 則通知}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"廣播"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止播送「<xliff:g id="APP_NAME">%1$s</xliff:g>」的內容嗎?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如果播送「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容或變更輸出來源,系統就會停止播送目前的內容"</string>
     <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..ac61ce6 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,7 @@
     <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>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Vula ngobuso. Swayiphela phezulu ukuze uvule."</string>
     <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>
@@ -833,7 +831,8 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"amadivayisi akhethiwe angu-<xliff:g id="COUNT">%1$d</xliff:g>"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(inqamukile)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Akukwazi ukushintsha. Thepha ukuze uzame futhi."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bhangqa idivayisi entsha"</string>
+    <!-- no translation found for media_output_dialog_pairing_new (5098212763195577270) -->
+    <skip />
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ukuze usakaze le seshini, sicela uvule i-app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"I-app engaziwa"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Misa ukusakaza"</string>
@@ -945,12 +944,21 @@
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"I-Wi-Fi ayitholakali"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Imodi ebalulekile"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"I-alamu isethiwe"</string>
+    <!-- no translation found for dream_overlay_status_bar_camera_off (5273073778969890823) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_mic_off (8366534415013819396) -->
+    <skip />
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Ikhamera nemakrofoni kuvaliwe"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{Isaziso esingu-#}one{Izaziso ezingu-#}other{Izaziso ezingu-#}}"</string>
+    <!-- no translation found for dream_overlay_weather_complication_desc (824503662089783824) -->
+    <skip />
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Ukusakaza"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Misa ukusakaza i-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Uma usakaza i-<xliff:g id="SWITCHAPP">%1$s</xliff:g> noma ushintsha okuphumayo, ukusakaza kwakho kwamanje kuzoma"</string>
     <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..f369bb2 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -553,7 +553,7 @@
     <dimen name="qs_dual_tile_padding_horizontal">6dp</dimen>
     <dimen name="qs_panel_elevation">4dp</dimen>
     <dimen name="qs_panel_padding_bottom">@dimen/footer_actions_height</dimen>
-    <dimen name="qs_panel_padding_top">48dp</dimen>
+    <dimen name="qs_panel_padding_top">80dp</dimen>
 
     <dimen name="qs_data_usage_text_size">14sp</dimen>
     <dimen name="qs_data_usage_usage_text_size">36sp</dimen>
@@ -564,6 +564,8 @@
     <dimen name="qs_footer_icon_size">20dp</dimen>
     <dimen name="qs_header_row_min_height">48dp</dimen>
 
+    <dimen name="qs_header_non_clickable_element_height">24dp</dimen>
+
     <dimen name="qs_footer_padding">20dp</dimen>
     <dimen name="qs_security_footer_height">88dp</dimen>
     <dimen name="qs_security_footer_single_line_height">48dp</dimen>
@@ -1443,6 +1445,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/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/xml/combined_qs_header_scene.xml b/packages/SystemUI/res/xml/combined_qs_header_scene.xml
index 0e83326..0fac76d 100644
--- a/packages/SystemUI/res/xml/combined_qs_header_scene.xml
+++ b/packages/SystemUI/res/xml/combined_qs_header_scene.xml
@@ -25,20 +25,109 @@
         <KeyFrameSet>
             <!-- These positions are to prevent visual movement of @id/date -->
             <KeyPosition
-                app:keyPositionType="pathRelative"
+                app:keyPositionType="deltaRelative"
                 app:percentX="0"
+                app:percentY="0"
                 app:framePosition="49"
+                app:percentWidth="1"
+                app:percentHeight="1"
+                app:curveFit="linear"
                 app:motionTarget="@id/date" />
             <KeyPosition
-                app:keyPositionType="pathRelative"
+                app:keyPositionType="deltaRelative"
                 app:percentX="1"
+                app:percentY="0.51"
                 app:framePosition="51"
+                app:percentWidth="1"
+                app:percentHeight="1"
+                app:curveFit="linear"
                 app:motionTarget="@id/date" />
             <KeyAttribute
                 app:motionTarget="@id/date"
-                app:framePosition="50"
+                app:framePosition="30"
                 android:alpha="0"
                 />
+            <KeyAttribute
+                app:motionTarget="@id/date"
+                app:framePosition="70"
+                android:alpha="0"
+                />
+            <KeyPosition
+                app:keyPositionType="pathRelative"
+                app:percentX="0"
+                app:percentY="0"
+                app:framePosition="0"
+                app:curveFit="linear"
+                app:motionTarget="@id/statusIcons" />
+            <KeyPosition
+                app:keyPositionType="pathRelative"
+                app:percentX="0"
+                app:percentY="0"
+                app:framePosition="50"
+                app:curveFit="linear"
+                app:motionTarget="@id/statusIcons" />
+            <KeyPosition
+                app:keyPositionType="deltaRelative"
+                app:percentX="1"
+                app:percentY="0.51"
+                app:framePosition="51"
+                app:curveFit="linear"
+                app:motionTarget="@id/statusIcons" />
+            <KeyAttribute
+                app:motionTarget="@id/statusIcons"
+                app:framePosition="30"
+                android:alpha="0"
+                />
+            <KeyAttribute
+                app:motionTarget="@id/statusIcons"
+                app:framePosition="70"
+                android:alpha="0"
+                />
+            <KeyPosition
+                app:keyPositionType="deltaRelative"
+                app:percentX="0"
+                app:percentY="0"
+                app:framePosition="50"
+                app:percentWidth="1"
+                app:percentHeight="1"
+                app:curveFit="linear"
+                app:motionTarget="@id/batteryRemainingIcon" />
+            <KeyPosition
+                app:keyPositionType="deltaRelative"
+                app:percentX="1"
+                app:percentY="0.51"
+                app:framePosition="51"
+                app:percentWidth="1"
+                app:percentHeight="1"
+                app:curveFit="linear"
+                app:motionTarget="@id/batteryRemainingIcon" />
+            <KeyAttribute
+                app:motionTarget="@id/batteryRemainingIcon"
+                app:framePosition="30"
+                android:alpha="0"
+                />
+            <KeyAttribute
+                app:motionTarget="@id/batteryRemainingIcon"
+                app:framePosition="70"
+                android:alpha="0"
+                />
+            <KeyPosition
+                app:motionTarget="@id/carrier_group"
+                app:percentX="1"
+                app:percentY="0.51"
+                app:framePosition="51"
+                app:percentWidth="1"
+                app:percentHeight="1"
+                app:curveFit="linear"
+                app:keyPositionType="deltaRelative" />
+            <KeyAttribute
+                app:motionTarget="@id/carrier_group"
+                app:framePosition="0"
+                android:alpha="0" />
+            <KeyAttribute
+                app:motionTarget="@id/carrier_group"
+                app:framePosition="70"
+                android:alpha="0" />
         </KeyFrameSet>
     </Transition>
 
diff --git a/packages/SystemUI/res/xml/large_screen_shade_header.xml b/packages/SystemUI/res/xml/large_screen_shade_header.xml
index 8909051..cdbf8ab 100644
--- a/packages/SystemUI/res/xml/large_screen_shade_header.xml
+++ b/packages/SystemUI/res/xml/large_screen_shade_header.xml
@@ -29,7 +29,12 @@
             app:layout_constraintTop_toTopOf="parent"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintEnd_toStartOf="@id/date"
+            app:layout_constraintHorizontal_bias="0"
         />
+        <Transform
+            android:scaleX="1"
+            android:scaleY="1"
+            />
     </Constraint>
 
     <Constraint
@@ -47,9 +52,38 @@
 
     <Constraint
         android:id="@+id/carrier_group">
+        <Layout
+            app:layout_constraintWidth_min="48dp"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            app:layout_constrainedWidth="true"
+            android:layout_gravity="end|center_vertical"
+            android:layout_marginStart="8dp"
+            app:layout_constraintStart_toEndOf="@id/date"
+            app:layout_constraintEnd_toStartOf="@id/statusIcons"
+            app:layout_constraintTop_toTopOf="@id/clock"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintHorizontal_bias="1"
+            />
         <PropertySet
             android:alpha="1"
-            app:customFloatValue="1"
+        />
+    </Constraint>
+
+    <Constraint
+        android:id="@+id/statusIcons">
+        <Layout
+            app:layout_constraintHeight_min="@dimen/large_screen_shade_header_min_height"
+            android:layout_width="wrap_content"
+            android:layout_height="@dimen/large_screen_shade_header_min_height"
+            app:layout_constraintStart_toEndOf="@id/carrier_group"
+            app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
+            app:layout_constraintTop_toTopOf="@id/clock"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintHorizontal_bias="1"
+            />
+        <PropertySet
+            android:alpha="1"
         />
     </Constraint>
 
@@ -64,6 +98,9 @@
             app:layout_constraintTop_toTopOf="@id/clock"
             app:layout_constraintBottom_toBottomOf="parent"
         />
+        <PropertySet
+            android:alpha="1"
+        />
     </Constraint>
 
     <Constraint
@@ -75,6 +112,7 @@
             app:layout_constraintTop_toTopOf="@id/date"
             app:layout_constraintBottom_toBottomOf="@id/date"
             app:layout_constraintStart_toEndOf="@id/batteryRemainingIcon"
+            app:layout_constraintHorizontal_bias="1"
         />
     </Constraint>
 
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/res/xml/qqs_header.xml b/packages/SystemUI/res/xml/qqs_header.xml
index c5b4c5d..ee0c4fb6 100644
--- a/packages/SystemUI/res/xml/qqs_header.xml
+++ b/packages/SystemUI/res/xml/qqs_header.xml
@@ -26,22 +26,27 @@
         <Layout
             android:layout_width="wrap_content"
             android:layout_height="0dp"
-            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintStart_toStartOf="@id/begin_guide"
             app:layout_constraintTop_toTopOf="parent"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintEnd_toStartOf="@id/date"
             app:layout_constraintHorizontal_bias="0"
             app:layout_constraintHorizontal_chainStyle="packed"
         />
+        <Transform
+            android:scaleX="1"
+            android:scaleY="1"
+            />
     </Constraint>
 
     <Constraint
         android:id="@+id/date">
         <Layout
-            android:layout_width="wrap_content"
+            android:layout_width="0dp"
             android:layout_height="0dp"
+            app:layout_constrainedWidth="true"
             app:layout_constraintStart_toEndOf="@id/clock"
-            app:layout_constraintEnd_toStartOf="@id/carrier_group"
+            app:layout_constraintEnd_toStartOf="@id/barrier"
             app:layout_constraintTop_toTopOf="parent"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintHorizontal_bias="0"
@@ -50,17 +55,41 @@
 
     <Constraint
         android:id="@+id/statusIcons">
+        <Layout
+            android:layout_width="0dp"
+            android:layout_height="@dimen/qs_header_non_clickable_element_height"
+            app:layout_constraintHeight_min="@dimen/qs_header_non_clickable_element_height"
+            app:layout_constraintStart_toEndOf="@id/date"
+            app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
+            app:layout_constraintTop_toTopOf="@id/date"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintHorizontal_bias="1"
+            />
     </Constraint>
 
     <Constraint
-        android:id="@+id/batteryRemainingIcon" >
+        android:id="@+id/batteryRemainingIcon">
+        <Layout
+            android:layout_width="wrap_content"
+            android:layout_height="@dimen/qs_header_non_clickable_element_height"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintHeight_min="@dimen/qs_header_non_clickable_element_height"
+            app:layout_constraintStart_toEndOf="@id/statusIcons"
+            app:layout_constraintEnd_toEndOf="@id/end_guide"
+            app:layout_constraintTop_toTopOf="@id/date"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintHorizontal_bias="1"
+            />
     </Constraint>
 
     <Constraint
         android:id="@+id/carrier_group">
-        <CustomAttribute
-            app:attributeName="alpha"
-            app:customFloatValue="0"
+        <Layout
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            />
+        <PropertySet
+            android:alpha="0"
         />
     </Constraint>
 
@@ -69,9 +98,11 @@
         <Layout
             android:layout_width="wrap_content"
             android:layout_height="0dp"
-            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@id/date"
+            app:layout_constraintEnd_toEndOf="@id/end_guide"
             app:layout_constraintTop_toTopOf="@id/date"
             app:layout_constraintBottom_toBottomOf="@id/date"
+            app:layout_constraintHorizontal_bias="1"
         />
     </Constraint>
 
diff --git a/packages/SystemUI/res/xml/qs_header_new.xml b/packages/SystemUI/res/xml/qs_header_new.xml
new file mode 100644
index 0000000..f39e6bd
--- /dev/null
+++ b/packages/SystemUI/res/xml/qs_header_new.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<ConstraintSet
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/qs_header_constraint"
+>
+
+    <Constraint
+        android:id="@+id/privacy_container">
+        <Layout
+            android:layout_width="wrap_content"
+            android:layout_height="@dimen/large_screen_shade_header_min_height"
+            app:layout_constraintEnd_toEndOf="@id/end_guide"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toTopOf="@id/carrier_group"
+            app:layout_constraintHorizontal_bias="1"
+            />
+    </Constraint>
+
+    <Constraint
+        android:id="@+id/clock">
+        <Layout
+            android:layout_width="wrap_content"
+            android:layout_height="@dimen/large_screen_shade_header_min_height"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/privacy_container"
+            app:layout_constraintBottom_toTopOf="@id/date"
+            app:layout_constraintEnd_toStartOf="@id/carrier_group"
+            app:layout_constraintHorizontal_bias="0"
+        />
+        <Transform
+            android:scaleX="2.4"
+            android:scaleY="2.4"
+            />
+    </Constraint>
+
+    <Constraint
+        android:id="@+id/date">
+        <Layout
+            android:layout_width="0dp"
+            android:layout_height="@dimen/qs_header_non_clickable_element_height"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/space"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/clock"
+            app:layout_constraintHorizontal_bias="0"
+            app:layout_constraintHorizontal_chainStyle="spread_inside"
+        />
+    </Constraint>
+
+    <Constraint
+        android:id="@+id/carrier_group">
+        <Layout
+            app:layout_constraintHeight_min="@dimen/large_screen_shade_header_min_height"
+            android:minHeight="@dimen/large_screen_shade_header_min_height"
+            app:layout_constraintWidth_min="48dp"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            app:layout_constraintStart_toEndOf="@id/clock"
+            app:layout_constraintTop_toBottomOf="@id/privacy_container"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="1"
+            app:layout_constraintBottom_toTopOf="@id/batteryRemainingIcon"
+            />
+        <PropertySet
+            android:alpha="1"
+            />
+    </Constraint>
+
+    <Constraint
+        android:id="@+id/statusIcons">
+        <Layout
+            android:layout_width="0dp"
+            android:layout_height="@dimen/qs_header_non_clickable_element_height"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintStart_toEndOf="@id/space"
+            app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
+            app:layout_constraintTop_toTopOf="@id/date"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintHorizontal_bias="1"
+            />
+    </Constraint>
+
+    <Constraint
+        android:id="@+id/batteryRemainingIcon">
+        <Layout
+            android:layout_width="wrap_content"
+            android:layout_height="@dimen/qs_header_non_clickable_element_height"
+            app:layout_constraintHeight_min="@dimen/qs_header_non_clickable_element_height"
+            app:layout_constraintStart_toEndOf="@id/statusIcons"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="@id/date"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintHorizontal_bias="1"
+            />
+    </Constraint>
+
+
+    <Constraint
+        android:id="@id/space">
+        <Layout
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            app:layout_constraintStart_toEndOf="@id/date"
+            app:layout_constraintEnd_toStartOf="@id/statusIcons"
+            />
+    </Constraint>
+</ConstraintSet>
\ No newline at end of file
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 564901c..0000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt
+++ /dev/null
@@ -1,223 +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.Build
-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.MSSIMMatcher
-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 matcher = if (shouldUsePerfectMatching()) {
-        PixelPerfectMatcher()
-    } else {
-        MSSIMMatcher()
-    }
-
-    private val screenshotRule =
-        ScreenshotTestRule(
-            SystemUIGoldenImagePathManager(
-                pathConfig,
-                currentGoldenIdentifier = {
-                    currentGoldenIdentifier ?: error("currentGoldenIdentifier is null")
-                },
-            )
-        )
-
-    private fun shouldUsePerfectMatching(): Boolean {
-        // 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.
-        return Build.CPU_ABI == "x86_64"
-    }
-
-    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, matcher)
-        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 6a80c48..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,
@@ -70,21 +126,78 @@
                     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")
-            try {
-                screenshotRule.screenshotTest(goldenIdentifier, dialog.window.decorView)
-            } finally {
-                dialog.dismiss()
+        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/navigationbar/RegionSamplingHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java
index 1d6a3bf..733470e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java
@@ -128,6 +128,14 @@
         mCallback = samplingCallback;
     }
 
+    /**
+     * Make callback accessible
+     */
+    @VisibleForTesting
+    public SamplingCallback getCallback() {
+        return mCallback;
+    }
+
     private void onDraw() {
         if (mWaitingOnDraw) {
             mWaitingOnDraw = false;
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..deabc27
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSamplingInstance.kt
@@ -0,0 +1,117 @@
+/*
+ * 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 androidx.annotation.VisibleForTesting
+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
+ */
+open class RegionSamplingInstance(
+        sampledView: View?,
+        mainExecutor: Executor?,
+        bgExecutor: Executor?,
+        regionSamplingEnabled: Boolean,
+        updateFun: UpdateColorCallback
+) {
+    private var isDark = RegionDarkness.DEFAULT
+    private var samplingBounds = Rect()
+    @VisibleForTesting 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()
+    }
+
+    @VisibleForTesting
+    open fun createRegionSamplingHelper(
+            sampledView: View,
+            callback: SamplingCallback,
+            mainExecutor: Executor?,
+            bgExecutor: Executor?
+    ): RegionSamplingHelper {
+        return RegionSamplingHelper(sampledView, callback, mainExecutor, bgExecutor)
+    }
+
+    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)
+    }
+
+    init {
+        if (regionSamplingEnabled && sampledView != null) {
+            regionSampler = createRegionSamplingHelper(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 43e7378..06e1828 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -650,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);
@@ -675,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 aaaa3f7..4c400a8 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -839,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;
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 69%
rename from packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
rename to packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
index ca94b8c..e9ca0fd 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,31 @@
             // 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 +160,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 +173,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..81da8023 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.shade.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/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
index aa67ecd..e16ac08 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
@@ -169,6 +169,7 @@
     private Animator mExitAnimator;
     private Animator mEnterAnimator;
     private final int mOrientation;
+    private boolean mKeyboardVisible;
 
 
     public ClipboardOverlayController(Context context,
@@ -261,8 +262,22 @@
         attachWindow();
         withWindowAttached(() -> {
             mWindow.setContentView(mView);
-            updateInsets(mWindowManager.getCurrentWindowMetrics().getWindowInsets());
-            mView.requestLayout();
+            WindowInsets insets = mWindowManager.getCurrentWindowMetrics().getWindowInsets();
+            mKeyboardVisible = insets.isVisible(WindowInsets.Type.ime());
+            updateInsets(insets);
+            mWindow.peekDecorView().getViewTreeObserver().addOnGlobalLayoutListener(
+                    new ViewTreeObserver.OnGlobalLayoutListener() {
+                        @Override
+                        public void onGlobalLayout() {
+                            WindowInsets insets =
+                                    mWindowManager.getCurrentWindowMetrics().getWindowInsets();
+                            boolean keyboardVisible = insets.isVisible(WindowInsets.Type.ime());
+                            if (keyboardVisible != mKeyboardVisible) {
+                                mKeyboardVisible = keyboardVisible;
+                                updateInsets(insets);
+                            }
+                        }
+                    });
             mWindow.peekDecorView().getViewRootImpl().setActivityConfigCallback(
                     new ViewRootImpl.ActivityConfigCallback() {
                         @Override
@@ -384,8 +399,6 @@
             mRemoteCopyChip.setVisibility(View.GONE);
         }
         withWindowAttached(() -> {
-            updateInsets(
-                    mWindowManager.getCurrentWindowMetrics().getWindowInsets());
             if (mEnterAnimator == null || !mEnterAnimator.isRunning()) {
                 mView.post(this::animateIn);
             }
@@ -509,7 +522,7 @@
     private void shareContent(ClipData clip) {
         mUiEventLogger.log(CLIPBOARD_OVERLAY_SHARE_TAPPED);
         Intent shareIntent = new Intent(Intent.ACTION_SEND);
-        shareIntent.putExtra(Intent.EXTRA_TEXT, clip.getItemAt(0).getText());
+        shareIntent.putExtra(Intent.EXTRA_TEXT, clip.getItemAt(0).getText().toString());
         shareIntent.setDataAndType(
                 clip.getItemAt(0).getUri(), clip.getDescription().getMimeType(0));
         shareIntent.putExtra(Intent.EXTRA_STREAM, clip.getItemAt(0).getUri());
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/controls/management/AppAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
index a174ed0..2389ad1 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
@@ -62,7 +62,7 @@
             backgroundExecutor.execute {
                 val collator = Collator.getInstance(resources.configuration.locales[0])
                 val localeComparator = compareBy<ControlsServiceInfo, CharSequence>(collator) {
-                    it.loadLabel()
+                    it.loadLabel() ?: ""
                 }
                 listOfServices = serviceInfos.sortedWith(localeComparator)
                 uiExecutor.execute(::notifyDataSetChanged)
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index 3a1b129..718befa 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;
@@ -31,26 +31,23 @@
 import com.android.systemui.media.taptotransfer.receiver.MediaTttChipControllerReceiver;
 import com.android.systemui.media.taptotransfer.sender.MediaTttChipControllerSender;
 import com.android.systemui.people.PeopleProvider;
+import com.android.systemui.statusbar.pipeline.ConnectivityInfoProcessor;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.unfold.FoldStateLogger;
 import com.android.systemui.unfold.FoldStateLoggingProvider;
 import com.android.systemui.unfold.SysUIUnfoldComponent;
 import com.android.systemui.unfold.UnfoldLatencyTracker;
 import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider;
-import com.android.wm.shell.ShellCommandHandler;
 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,12 +96,6 @@
         Builder setTaskViewFactory(Optional<TaskViewFactory> t);
 
         @BindsInstance
-        Builder setHideDisplayCutout(Optional<HideDisplayCutout> h);
-
-        @BindsInstance
-        Builder setShellCommandHandler(Optional<ShellCommandHandler> shellDump);
-
-        @BindsInstance
         Builder setTransitions(ShellTransitions t);
 
         @BindsInstance
@@ -111,18 +105,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();
@@ -146,6 +131,7 @@
         getMediaTttCommandLineHelper();
         getMediaMuteAwaitConnectionCli();
         getNearbyMediaDevicesManager();
+        getConnectivityInfoProcessor();
         getUnfoldLatencyTracker().init();
         getFoldStateLoggingProvider().ifPresent(FoldStateLoggingProvider::init);
         getFoldStateLogger().ifPresent(FoldStateLogger::init);
@@ -228,6 +214,9 @@
     /** */
     Optional<NearbyMediaDevicesManager> getNearbyMediaDevicesManager();
 
+    /** */
+    Optional<ConnectivityInfoProcessor> getConnectivityInfoProcessor();
+
     /**
      * Returns {@link CoreStartable}s that should be started with the application.
      */
@@ -241,7 +230,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 137e288..ceb702e 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;
@@ -46,11 +45,12 @@
 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;
@@ -70,7 +70,7 @@
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
-import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.pipeline.dagger.StatusBarPipelineModule;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -82,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;
@@ -114,6 +115,7 @@
             AssistModule.class,
             BiometricsModule.class,
             ClockModule.class,
+            CoroutinesModule.class,
             DreamModule.class,
             ControlsModule.class,
             DemoModeModule.class,
@@ -122,15 +124,17 @@
             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,
+            StatusBarPipelineModule.class,
             StatusBarPolicyModule.class,
             StatusBarWindowModule.class,
             SysUIConcurrencyModule.class,
@@ -198,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
@@ -212,7 +211,6 @@
             NotificationShadeWindowController notificationShadeWindowController,
             KeyguardStateController keyguardStateController,
             ShadeController shadeController,
-            ConfigurationController configurationController,
             @Nullable IStatusBarService statusBarService,
             INotificationManager notificationManager,
             NotificationVisibilityProvider visibilityProvider,
@@ -230,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..78a45f9 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
@@ -21,27 +21,24 @@
 
 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;
+import com.android.wm.shell.sysui.ShellCommandHandler;
+import com.android.wm.shell.sysui.ShellInit;
 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.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}
@@ -78,14 +75,24 @@
      * Initializes all the WMShell components before starting any of the SystemUI components.
      */
     default void init() {
-        getShellInit().init();
+        // TODO(238217847): To be removed once the dependencies are inverted and ShellController can
+        // inject these classes directly, otherwise, it's currently needed to ensure that these
+        // classes are created and set on the controller before onInit() is called
+        getShellInit();
+        getShellCommandHandler();
+        getShell().onInit();
     }
 
     @WMSingleton
+    ShellInterface getShell();
+
+    // TODO(238217847): To be removed once ShellController can inject ShellInit directly
+    @WMSingleton
     ShellInit getShellInit();
 
+    // TODO(238217847): To be removed once ShellController can inject ShellCommandHandler directly
     @WMSingleton
-    Optional<ShellCommandHandler> getShellCommandHandler();
+    ShellCommandHandler getShellCommandHandler();
 
     @WMSingleton
     Optional<OneHanded> getOneHanded();
@@ -100,9 +107,6 @@
     Optional<Bubbles> getBubbles();
 
     @WMSingleton
-    Optional<HideDisplayCutout> getHideDisplayCutout();
-
-    @WMSingleton
     Optional<TaskViewFactory> getTaskViewFactory();
 
     @WMSingleton
@@ -115,17 +119,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/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/dreams/touch/dagger/BouncerSwipeModule.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java
index b9436f9..9c22dc6 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java
@@ -25,7 +25,7 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.touch.BouncerSwipeTouchHandler;
 import com.android.systemui.dreams.touch.DreamTouchHandler;
-import com.android.systemui.statusbar.phone.PanelViewController;
+import com.android.systemui.shade.PanelViewController;
 import com.android.wm.shell.animation.FlingAnimationUtils;
 
 import javax.inject.Named;
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index 2fa104a..73bc92d2 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -63,6 +63,9 @@
     public static final BooleanFlag REMOVE_UNRANKED_NOTIFICATIONS =
             new BooleanFlag(109, false);
 
+    public static final BooleanFlag FSI_REQUIRES_KEYGUARD =
+            new BooleanFlag(110, false, true);
+
     /***************************************/
     // 200 - keyguard/lockscreen
 
@@ -119,7 +122,7 @@
             new BooleanFlag(500, true);
 
     public static final BooleanFlag COMBINED_QS_HEADERS =
-            new BooleanFlag(501, false);
+            new BooleanFlag(501, false, true);
 
     public static final ResourceBooleanFlag PEOPLE_TILE =
             new ResourceBooleanFlag(502, R.bool.flag_conversations);
@@ -133,7 +136,7 @@
     @Deprecated
     public static final BooleanFlag NEW_FOOTER = new BooleanFlag(504, true);
 
-    public static final BooleanFlag NEW_HEADER = new BooleanFlag(505, false);
+    public static final BooleanFlag NEW_HEADER = new BooleanFlag(505, false, true);
     public static final ResourceBooleanFlag FULL_SCREEN_USER_SWITCHER =
             new ResourceBooleanFlag(506, R.bool.config_enableFullscreenUserSwitcher);
 
@@ -145,6 +148,11 @@
     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);
+
+    public static final BooleanFlag NEW_STATUS_BAR_PIPELINE = new BooleanFlag(604, false);
+
     /***************************************/
     // 700 - dialer/calls
     public static final BooleanFlag ONGOING_CALL_STATUS_BAR_CHIP =
@@ -176,7 +184,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 +215,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 7abf2a8..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
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/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/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..2006d53 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -30,10 +30,10 @@
 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
-import android.window.BackEvent
 import androidx.dynamicanimation.animation.DynamicAnimation
 import androidx.dynamicanimation.animation.SpringForce
 import com.android.internal.util.LatencyTracker
@@ -96,8 +96,8 @@
 
 class BackPanelController private constructor(
     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 +112,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,
@@ -121,8 +122,8 @@
         fun create(context: Context, backAnimation: BackAnimation?): BackPanelController {
             val backPanelController = BackPanelController(
                 context,
-                backAnimation,
                 windowManager,
+                viewConfiguration,
                 mainHandler,
                 vibratorHelper,
                 configurationController,
@@ -164,6 +165,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 {
@@ -258,7 +263,6 @@
      */
     private fun updateConfiguration() {
         params.update(resources)
-        updateBackAnimationSwipeThresholds()
         mView.updateArrowPaint(params.arrowThickness)
     }
 
@@ -290,13 +294,6 @@
     }
 
     override fun onMotionEvent(event: MotionEvent) {
-        backAnimation?.onBackMotion(
-            event.x,
-            event.y,
-            event.actionMasked,
-            if (mView.isLeftPanel) BackEvent.EDGE_LEFT else BackEvent.EDGE_RIGHT
-        )
-
         velocityTracker!!.addMovement(event)
         when (event.actionMasked) {
             MotionEvent.ACTION_DOWN -> {
@@ -304,29 +301,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
@@ -451,18 +472,6 @@
         )
     }
 
-    fun setBackAnimation(backAnimation: BackAnimation?) {
-        this.backAnimation = backAnimation
-        updateBackAnimationSwipeThresholds()
-    }
-
-    private fun updateBackAnimationSwipeThresholds() {
-        backAnimation?.setSwipeThresholds(
-            params.swipeTriggerThreshold,
-            fullyStretchedThreshold
-        )
-    }
-
     override fun onDestroy() {
         cancelFailsafe()
         windowManager.removeView(mView)
@@ -530,11 +539,11 @@
     }
 
     private fun resetOnDown() {
+        hasPassedDragSlop = false
         hasHapticPlayed = false
         totalTouchDelta = 0f
         vibrationTime = 0
         cancelFailsafe()
-        backAnimation?.setTriggerBack(false)
     }
 
     private fun updateYPosition(touchY: Float) {
@@ -547,7 +556,6 @@
     override fun setDisplaySize(displaySize: Point) {
         this.displaySize.set(displaySize.x, displaySize.y)
         fullyStretchedThreshold = min(displaySize.x.toFloat(), params.swipeProgressThreshold)
-        updateBackAnimationSwipeThresholds()
     }
 
     /**
@@ -631,7 +639,6 @@
                 updateRestingArrowDimens(animated = true, currentState)
             }
             GestureState.ACTIVE -> {
-                backAnimation?.setTriggerBack(true)
                 updateRestingArrowDimens(animated = true, currentState)
                 // Vibrate the first time we transition to ACTIVE
                 if (!hasHapticPlayed) {
@@ -641,7 +648,6 @@
                 }
             }
             GestureState.INACTIVE -> {
-                backAnimation?.setTriggerBack(false)
                 updateRestingArrowDimens(animated = true, currentState)
             }
             GestureState.FLUNG -> playFlingBackAnimation()
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..057ed24 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,7 @@
 import android.view.Surface;
 import android.view.ViewConfiguration;
 import android.view.WindowManager;
-import android.view.WindowMetrics;
+import android.window.BackEvent;
 
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.policy.GestureNavigationSettingsObserver;
@@ -133,7 +133,7 @@
                 @Override
                 public void onPrioritizedRotation(@Surface.Rotation int rotation) {
                     mStartingQuickstepRotation = rotation;
-                    updateDisabledForQuickstep(mContext.getResources().getConfiguration());
+                    updateDisabledForQuickstep(mLastReportedConfig);
                 }
             };
 
@@ -183,6 +183,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<>();
 
@@ -208,6 +209,10 @@
     private float mBottomGestureHeight;
     // The slop to distinguish between horizontal and vertical motion
     private float mTouchSlop;
+    // The threshold for triggering back
+    private float mBackSwipeTriggerThreshold;
+    // The threshold for back swipe full progress.
+    private float mBackSwipeProgressThreshold;
     // Duration after which we consider the event as longpress.
     private final int mLongPressTimeout;
     private int mStartingQuickstepRotation = -1;
@@ -274,6 +279,8 @@
                             Log.d(DEBUG_MISSING_GESTURE_TAG, "Triggered back: down="
                                     + sendDown + ", up=" + sendUp);
                         }
+                    } else {
+                        mBackAnimation.setTriggerBack(true);
                     }
 
                     mOverviewProxyService.notifyBackAction(true, (int) mDownPoint.x,
@@ -285,6 +292,9 @@
 
                 @Override
                 public void cancelBack() {
+                    if (mBackAnimation != null) {
+                        mBackAnimation.setTriggerBack(false);
+                    }
                     logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE);
                     mOverviewProxyService.notifyBackAction(false, (int) mDownPoint.x,
                             (int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge);
@@ -338,6 +348,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) {
@@ -405,6 +416,11 @@
         final float backGestureSlop = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_SYSTEMUI,
                         SystemUiDeviceConfigFlags.BACK_GESTURE_SLOP_MULTIPLIER, 0.75f);
         mTouchSlop = mViewConfiguration.getScaledTouchSlop() * backGestureSlop;
+        mBackSwipeTriggerThreshold = res.getDimension(
+                R.dimen.navigation_edge_action_drag_threshold);
+        mBackSwipeProgressThreshold = res.getDimension(
+                R.dimen.navigation_edge_action_progress_threshold);
+        updateBackAnimationThresholds();
     }
 
     public void updateNavigationBarOverlayExcludeRegion(Rect exclude) {
@@ -747,6 +763,7 @@
         MotionEvent cancelEv = MotionEvent.obtain(ev);
         cancelEv.setAction(MotionEvent.ACTION_CANCEL);
         mEdgeBackPlugin.onMotionEvent(cancelEv);
+        dispatchToBackAnimation(cancelEv);
         cancelEv.recycle();
     }
 
@@ -793,6 +810,7 @@
             if (mAllowGesture) {
                 mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge);
                 mEdgeBackPlugin.onMotionEvent(ev);
+                dispatchToBackAnimation(ev);
             }
             if (mLogGesture) {
                 mDownPoint.set(ev.getX(), ev.getY());
@@ -866,12 +884,23 @@
             if (mAllowGesture) {
                 // forward touch
                 mEdgeBackPlugin.onMotionEvent(ev);
+                dispatchToBackAnimation(ev);
             }
         }
 
         mProtoTracer.scheduleFrameUpdate();
     }
 
+    private void dispatchToBackAnimation(MotionEvent event) {
+        if (mBackAnimation != null) {
+            mBackAnimation.onBackMotion(
+                    event.getX(),
+                    event.getY(),
+                    event.getActionMasked(),
+                    mIsOnLeftEdge ? BackEvent.EDGE_LEFT : BackEvent.EDGE_RIGHT);
+        }
+    }
+
     private void updateDisabledForQuickstep(Configuration newConfig) {
         int rotation = newConfig.windowConfiguration.getRotation();
         mDisabledForQuickstep = mStartingQuickstepRotation > -1 &&
@@ -886,12 +915,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);
@@ -899,6 +928,16 @@
         if (mEdgeBackPlugin != null) {
             mEdgeBackPlugin.setDisplaySize(mDisplaySize);
         }
+        updateBackAnimationThresholds();
+    }
+
+    private void updateBackAnimationThresholds() {
+        if (mBackAnimation == null) {
+            return;
+        }
+        mBackAnimation.setSwipeThresholds(
+                mBackSwipeTriggerThreshold,
+                Math.min(mDisplaySize.x, mBackSwipeProgressThreshold));
     }
 
     private boolean sendEvent(int action, int code) {
@@ -978,13 +1017,7 @@
 
     public void setBackAnimation(BackAnimation backAnimation) {
         mBackAnimation = backAnimation;
-        if (mEdgeBackPlugin != null) {
-            if (mEdgeBackPlugin instanceof NavigationBarEdgePanel) {
-                ((NavigationBarEdgePanel) mEdgeBackPlugin).setBackAnimation(backAnimation);
-            } else if (mEdgeBackPlugin instanceof BackPanelController) {
-                ((BackPanelController) mEdgeBackPlugin).setBackAnimation(backAnimation);
-            }
-        }
+        updateBackAnimationThresholds();
     }
 
     /**
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..7cc95a1 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
@@ -19,169 +19,63 @@
 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;
 
     @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);
+
+        PeopleViewModel viewModel = new ViewModelProvider(this, mViewModelFactory).get(
+                PeopleViewModel.class);
+
+        // Update the widget ID coming from the intent.
+        int widgetId = getIntent().getIntExtra(EXTRA_APPWIDGET_ID, INVALID_APPWIDGET_ID);
+        viewModel.onWidgetIdChanged(widgetId);
+
+        ViewGroup view = PeopleViewBinder.create(this);
+        PeopleViewBinder.bind(view, viewModel, /* lifecycleOwner= */ this,
+                (result) -> {
+                    finishActivity(result);
+                    return null;
+                });
+        setContentView(view);
     }
 
-    /** 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);
+    private void finishActivity(PeopleViewModel.Result result) {
+        if (result instanceof PeopleViewModel.Result.Success) {
+            if (DEBUG) Log.d(TAG, "Widget added!");
+            Intent data = ((PeopleViewModel.Result.Success) result).getData();
+            setResult(RESULT_OK, data);
+        } else {
+            if (DEBUG) Log.d(TAG, "Activity dismissed with no widgets added!");
+            setResult(RESULT_CANCELED);
         }
-
-        // 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();
-    }
-
-    /** Finish activity with a successful widget configuration result. */
-    private void finishActivity() {
-        if (DEBUG) Log.d(TAG, "Widget added!");
-        setActivityResult(RESULT_OK);
         finish();
     }
-
-    /** Finish activity without choosing a widget. */
-    public void dismissActivity(View v) {
-        if (DEBUG) Log.d(TAG, "Activity dismissed with no widgets added!");
-        finish();
-    }
-
-    private void setActivityResult(int result) {
-        Intent resultValue = new Intent();
-        resultValue.putExtra(EXTRA_APPWIDGET_ID, mAppWidgetId);
-        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..d8a429e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt
@@ -0,0 +1,247 @@
+/*
+ * 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 = "PeopleViewBinder"
+
+    /**
+     * 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,
+        onResult: (PeopleViewModel.Result) -> Unit,
+    ) {
+        // Call [onResult] as soon as a result is available.
+        lifecycleOwner.lifecycleScope.launch {
+            lifecycleOwner.repeatOnLifecycle(CREATED) {
+                viewModel.result.collect { result ->
+                    if (result != null) {
+                        viewModel.clearResult()
+                        onResult(result)
+                    }
+                }
+            }
+        }
+
+        // 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, viewModel::onUserJourneyCancelled)
+                        }
+                    }
+            }
+        }
+
+        // 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, onGotItClicked: () -> Unit) {
+        // 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)
+
+        noConversationsView.findViewById<View>(R.id.got_it_button).setOnClickListener {
+            onGotItClicked()
+        }
+
+        // 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/core/java/android/app/timedetector/GnssTimeSuggestion.aidl b/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleTileViewModel.kt
similarity index 60%
copy from core/java/android/app/timedetector/GnssTimeSuggestion.aidl
copy to packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleTileViewModel.kt
index 81475ec..40205ce 100644
--- a/core/java/android/app/timedetector/GnssTimeSuggestion.aidl
+++ b/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleTileViewModel.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 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.
@@ -14,6 +14,14 @@
  * limitations under the License.
  */
 
-package android.app.timedetector;
+package com.android.systemui.people.ui.viewmodel
 
-parcelable GnssTimeSuggestion;
+import android.graphics.Bitmap
+import com.android.systemui.people.widget.PeopleTileKey
+
+/** 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..0834a5a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt
@@ -0,0 +1,163 @@
+/*
+ * 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.EXTRA_APPWIDGET_ID
+import android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID
+import android.content.Context
+import android.content.Intent
+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
+import kotlinx.coroutines.flow.asStateFlow
+
+/**
+ * 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.asStateFlow()
+
+    /**
+     * 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.asStateFlow()
+
+    /** The ID of the widget currently being edited/added. */
+    private val _appWidgetId = MutableStateFlow(INVALID_APPWIDGET_ID)
+    val appWidgetId: StateFlow<Int> = _appWidgetId.asStateFlow()
+
+    /** The result of this user journey. */
+    private val _result = MutableStateFlow<Result?>(null)
+    val result: StateFlow<Result?> = _result.asStateFlow()
+
+    /** 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 [result], setting it to null. */
+    fun clearResult() {
+        _result.value = null
+    }
+
+    /** Called when a tile is clicked. */
+    fun onTileClicked(tile: PeopleTileViewModel) {
+        val widgetId = _appWidgetId.value
+        if (PeopleSpaceUtils.DEBUG) {
+            Log.d(
+                TAG,
+                "Put ${tile.username}'s shortcut ID: ${tile.key.shortcutId} for widget ID $widgetId"
+            )
+        }
+        widgetRepository.setWidgetTile(widgetId, tile.key)
+        _result.value =
+            Result.Success(Intent().apply { putExtra(EXTRA_APPWIDGET_ID, appWidgetId.value) })
+    }
+
+    /** Called when this user journey is cancelled. */
+    fun onUserJourneyCancelled() {
+        _result.value = Result.Cancelled
+    }
+
+    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
+        }
+    }
+
+    sealed class Result {
+        class Success(val data: Intent) : Result()
+        object Cancelled : Result()
+    }
+
+    companion object {
+        private const val TAG = "PeopleViewModel"
+    }
+}
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/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index a1c66b3..4552abd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -19,8 +19,6 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.os.Build;
-import android.os.Handler;
-import android.os.Looper;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings.Secure;
@@ -28,6 +26,7 @@
 import android.util.ArraySet;
 import android.util.Log;
 
+import androidx.annotation.MainThread;
 import androidx.annotation.Nullable;
 
 import com.android.internal.logging.InstanceId;
@@ -35,9 +34,7 @@
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
-import com.android.systemui.broadcast.BroadcastDispatcher;
 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.plugins.PluginListener;
@@ -68,12 +65,20 @@
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
+import java.util.concurrent.Executor;
 import java.util.function.Predicate;
 
 import javax.inject.Inject;
 import javax.inject.Provider;
 
-/** Platform implementation of the quick settings tile host **/
+/** Platform implementation of the quick settings tile host
+ *
+ * This class keeps track of the set of current tiles and is the in memory source of truth
+ * (ground truth is kept in {@link Secure#QS_TILES}). When the ground truth changes,
+ * {@link #onTuningChanged} will be called and the tiles will be re-created as needed.
+ *
+ * This class also provides the interface for adding/removing/changing tiles.
+ */
 @SysUISingleton
 public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, Dumpable {
     private static final String TAG = "QSTileHost";
@@ -89,11 +94,11 @@
     private final TunerService mTunerService;
     private final PluginManager mPluginManager;
     private final DumpManager mDumpManager;
-    private final BroadcastDispatcher mBroadcastDispatcher;
     private final QSLogger mQSLogger;
     private final UiEventLogger mUiEventLogger;
     private final InstanceIdSequence mInstanceIdSequence;
     private final CustomTileStatePersister mCustomTileStatePersister;
+    private final Executor mMainExecutor;
 
     private final List<Callback> mCallbacks = new ArrayList<>();
     @Nullable
@@ -113,13 +118,11 @@
     public QSTileHost(Context context,
             StatusBarIconController iconController,
             QSFactory defaultFactory,
-            @Main Handler mainHandler,
-            @Background Looper bgLooper,
+            @Main Executor mainExecutor,
             PluginManager pluginManager,
             TunerService tunerService,
             Provider<AutoTileManager> autoTiles,
             DumpManager dumpManager,
-            BroadcastDispatcher broadcastDispatcher,
             Optional<CentralSurfaces> centralSurfacesOptional,
             QSLogger qsLogger,
             UiEventLogger uiEventLogger,
@@ -137,7 +140,7 @@
         mDumpManager = dumpManager;
         mQSLogger = qsLogger;
         mUiEventLogger = uiEventLogger;
-        mBroadcastDispatcher = broadcastDispatcher;
+        mMainExecutor = mainExecutor;
         mTileServiceRequestController = tileServiceRequestControllerBuilder.create(this);
         mTileLifeCycleManagerFactory = tileLifecycleManagerFactory;
 
@@ -151,7 +154,7 @@
         mSecureSettings = secureSettings;
         mCustomTileStatePersister = customTileStatePersister;
 
-        mainHandler.post(() -> {
+        mainExecutor.execute(() -> {
             // This is technically a hack to avoid circular dependency of
             // QSTileHost -> XXXTile -> QSTileHost. Posting ensures creation
             // finishes before creating any tiles.
@@ -258,6 +261,33 @@
         return mTileSpecs.indexOf(spec);
     }
 
+    /**
+     * Whenever the Secure Setting keeping track of the current tiles changes (or upon start) this
+     * will be called with the new value of the setting.
+     *
+     * This method will do the following:
+     * <ol>
+     *     <li>Destroy any existing tile that's not one of the current tiles (in the setting)</li>
+     *     <li>Create new tiles for those that don't already exist. If this tiles end up being
+     *         not available, they'll also be destroyed.</li>
+     *     <li>Save the resolved list of tiles (current tiles that are available) into the setting.
+     *         This means that after this call ends, the tiles in the Setting, {@link #mTileSpecs},
+     *         and visible tiles ({@link #mTiles}) must match.
+     *         </li>
+     * </ol>
+     *
+     * Additionally, if the user has changed, it'll do the following:
+     * <ul>
+     *     <li>Change the user for SystemUI tiles: {@link QSTile#userSwitch}.</li>
+     *     <li>Destroy any {@link CustomTile} and recreate it for the new user.</li>
+     * </ul>
+     *
+     * This happens in main thread as {@link com.android.systemui.tuner.TunerServiceImpl} dispatches
+     * in main thread.
+     *
+     * @see QSTile#isAvailable
+     */
+    @MainThread
     @Override
     public void onTuningChanged(String key, String newValue) {
         if (!TILES_SETTING.equals(key)) {
@@ -330,34 +360,44 @@
         mCurrentUser = currentUser;
         List<String> currentSpecs = new ArrayList<>(mTileSpecs);
         mTileSpecs.clear();
-        mTileSpecs.addAll(tileSpecs);
+        mTileSpecs.addAll(newTiles.keySet()); // Only add the valid (available) tiles.
         mTiles.clear();
         mTiles.putAll(newTiles);
         if (newTiles.isEmpty() && !tileSpecs.isEmpty()) {
             // If we didn't manage to create any tiles, set it to empty (default)
             Log.d(TAG, "No valid tiles on tuning changed. Setting to default.");
-            changeTiles(currentSpecs, loadTileSpecs(mContext, ""));
+            changeTilesByUser(currentSpecs, loadTileSpecs(mContext, ""));
         } else {
+            String resolvedTiles = TextUtils.join(",", mTileSpecs);
+            if (!resolvedTiles.equals(newValue)) {
+                // If the resolved tiles (those we actually ended up with) are different than
+                // the ones that are in the setting, update the Setting.
+                saveTilesToSettings(mTileSpecs);
+            }
             for (int i = 0; i < mCallbacks.size(); i++) {
                 mCallbacks.get(i).onTilesChanged();
             }
         }
     }
 
+    /**
+     * Only use with [CustomTile] if the tile doesn't exist anymore (and therefore doesn't need
+     * its lifecycle terminated).
+     */
     @Override
     public void removeTile(String spec) {
-        changeTileSpecs(tileSpecs-> tileSpecs.remove(spec));
+        mMainExecutor.execute(() -> changeTileSpecs(tileSpecs-> tileSpecs.remove(spec)));
     }
 
     /**
      * Remove many tiles at once.
      *
-     * It will only save to settings once (as opposed to {@link QSTileHost#removeTile} called
+     * It will only save to settings once (as opposed to {@link QSTileHost#removeTileByUser} called
      * multiple times).
      */
     @Override
     public void removeTiles(Collection<String> specs) {
-        changeTileSpecs(tileSpecs -> tileSpecs.removeAll(specs));
+        mMainExecutor.execute(() -> changeTileSpecs(tileSpecs -> tileSpecs.removeAll(specs)));
     }
 
     @Override
@@ -381,26 +421,29 @@
      * @param requestPosition -1 for end, 0 for beginning, or X for insertion at position X
      */
     public void addTile(String spec, int requestPosition) {
-        if (spec.equals("work")) Log.wtfStack(TAG, "Adding work tile");
-        changeTileSpecs(tileSpecs -> {
-            if (tileSpecs.contains(spec)) return false;
+        mMainExecutor.execute(() ->
+                changeTileSpecs(tileSpecs -> {
+                    if (tileSpecs.contains(spec)) return false;
 
-            int size = tileSpecs.size();
-            if (requestPosition == POSITION_AT_END || requestPosition >= size) {
-                tileSpecs.add(spec);
-            } else {
-                tileSpecs.add(requestPosition, spec);
-            }
-            return true;
-        });
+                    int size = tileSpecs.size();
+                    if (requestPosition == POSITION_AT_END || requestPosition >= size) {
+                        tileSpecs.add(spec);
+                    } else {
+                        tileSpecs.add(requestPosition, spec);
+                    }
+                    return true;
+                })
+        );
     }
 
-    void saveTilesToSettings(List<String> tileSpecs) {
+    @MainThread
+    private void saveTilesToSettings(List<String> tileSpecs) {
         mSecureSettings.putStringForUser(TILES_SETTING, TextUtils.join(",", tileSpecs),
                 null /* tag */, false /* default */, mCurrentUser,
                 true /* overrideable by restore */);
     }
 
+    @MainThread
     private void changeTileSpecs(Predicate<List<String>> changeFunction) {
         final String setting = mSecureSettings.getStringForUser(TILES_SETTING, mCurrentUser);
         final List<String> tileSpecs = loadTileSpecs(mContext, setting);
@@ -420,29 +463,32 @@
      */
     public void addTile(ComponentName tile, boolean end) {
         String spec = CustomTile.toSpec(tile);
-        if (!mTileSpecs.contains(spec)) {
-            List<String> newSpecs = new ArrayList<>(mTileSpecs);
-            if (end) {
-                newSpecs.add(spec);
-            } else {
-                newSpecs.add(0, spec);
-            }
-            changeTiles(mTileSpecs, newSpecs);
-        }
+        addTile(spec, end ? POSITION_AT_END : 0);
     }
 
-    public void removeTile(ComponentName tile) {
-        List<String> newSpecs = new ArrayList<>(mTileSpecs);
-        newSpecs.remove(CustomTile.toSpec(tile));
-        changeTiles(mTileSpecs, newSpecs);
+    /**
+     * This will call through {@link #changeTilesByUser}. It should only be used when a tile is
+     * removed by a <b>user action</b> like {@code adb}.
+     */
+    public void removeTileByUser(ComponentName tile) {
+        mMainExecutor.execute(() -> {
+            List<String> newSpecs = new ArrayList<>(mTileSpecs);
+            if (newSpecs.remove(CustomTile.toSpec(tile))) {
+                changeTilesByUser(mTileSpecs, newSpecs);
+            }
+        });
     }
 
     /**
      * Change the tiles triggered by the user editing.
      * <p>
      * This is not called on device start, or on user change.
+     *
+     * {@link android.service.quicksettings.TileService#onTileRemoved} will be called for tiles
+     * that are removed.
      */
-    public void changeTiles(List<String> previousTiles, List<String> newTiles) {
+    @MainThread
+    public void changeTilesByUser(List<String> previousTiles, List<String> newTiles) {
         final List<String> copy = new ArrayList<>(previousTiles);
         final int NP = copy.size();
         for (int i = 0; i < NP; i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
index ec0d081..eeb1010 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
@@ -134,18 +134,9 @@
         mQSCarrierGroupController
                 .setOnSingleCarrierChangedListener(mView::setIsSingleCarrier);
 
-        List<String> rssiIgnoredSlots;
-
-        if (mFeatureFlags.isEnabled(Flags.COMBINED_STATUS_BAR_SIGNAL_ICONS)) {
-            rssiIgnoredSlots = List.of(
-                    getResources().getString(com.android.internal.R.string.status_bar_no_calling),
-                    getResources().getString(com.android.internal.R.string.status_bar_call_strength)
-            );
-        } else {
-            rssiIgnoredSlots = List.of(
-                    getResources().getString(com.android.internal.R.string.status_bar_mobile)
-            );
-        }
+        List<String> rssiIgnoredSlots = List.of(
+                getResources().getString(com.android.internal.R.string.status_bar_mobile)
+        );
 
         mView.onAttach(mIconManager, mQSExpansionPathInterpolator, rssiIgnoredSlots,
                 mInsetsProvider, mFeatureFlags.isEnabled(Flags.COMBINED_QS_HEADERS));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/carrier/CellSignalState.kt b/packages/SystemUI/src/com/android/systemui/qs/carrier/CellSignalState.kt
index 2dac639..e925b54 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/carrier/CellSignalState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/carrier/CellSignalState.kt
@@ -27,7 +27,6 @@
     @JvmField val contentDescription: String? = null,
     @JvmField val typeContentDescription: String? = null,
     @JvmField val roaming: Boolean = false,
-    @JvmField val providerModelBehavior: Boolean = false
 ) {
     /**
      * Changes the visibility of this state by returning a copy with the visibility changed.
@@ -41,4 +40,4 @@
         if (this.visible == visible) return this
         else return copy(visible = visible)
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrier.java b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrier.java
index 592da65..703b95a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrier.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrier.java
@@ -45,7 +45,7 @@
     private View mSpacer;
     @Nullable
     private CellSignalState mLastSignalState;
-    private boolean mProviderModelInitialized = false;
+    private boolean mMobileSignalInitialized = false;
     private boolean mIsSingleCarrier;
 
     public QSCarrier(Context context) {
@@ -96,35 +96,25 @@
             mMobileRoaming.setImageTintList(colorStateList);
             mMobileSignal.setImageTintList(colorStateList);
 
-            if (state.providerModelBehavior) {
-                if (!mProviderModelInitialized) {
-                    mProviderModelInitialized = true;
-                    mMobileSignal.setImageDrawable(
-                            mContext.getDrawable(R.drawable.ic_qs_no_calling_sms));
-                }
-                mMobileSignal.setImageDrawable(mContext.getDrawable(state.mobileSignalIconId));
-                mMobileSignal.setContentDescription(state.contentDescription);
-            } else {
-                if (!mProviderModelInitialized) {
-                    mProviderModelInitialized = true;
-                    mMobileSignal.setImageDrawable(new SignalDrawable(mContext));
-                }
-                mMobileSignal.setImageLevel(state.mobileSignalIconId);
-                StringBuilder contentDescription = new StringBuilder();
-                if (state.contentDescription != null) {
-                    contentDescription.append(state.contentDescription).append(", ");
-                }
-                if (state.roaming) {
-                    contentDescription
-                            .append(mContext.getString(R.string.data_connection_roaming))
-                            .append(", ");
-                }
-                // TODO: show mobile data off/no internet text for 5 seconds before carrier text
-                if (hasValidTypeContentDescription(state.typeContentDescription)) {
-                    contentDescription.append(state.typeContentDescription);
-                }
-                mMobileSignal.setContentDescription(contentDescription);
+            if (!mMobileSignalInitialized) {
+                mMobileSignalInitialized = true;
+                mMobileSignal.setImageDrawable(new SignalDrawable(mContext));
             }
+            mMobileSignal.setImageLevel(state.mobileSignalIconId);
+            StringBuilder contentDescription = new StringBuilder();
+            if (state.contentDescription != null) {
+                contentDescription.append(state.contentDescription).append(", ");
+            }
+            if (state.roaming) {
+                contentDescription
+                        .append(mContext.getString(R.string.data_connection_roaming))
+                        .append(", ");
+            }
+            // TODO: show mobile data off/no internet text for 5 seconds before carrier text
+            if (hasValidTypeContentDescription(state.typeContentDescription)) {
+                contentDescription.append(state.typeContentDescription);
+            }
+            mMobileSignal.setContentDescription(contentDescription);
         }
         return true;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java
index 6908e5a..cb76ee2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java
@@ -42,10 +42,7 @@
 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;
 import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.statusbar.connectivity.IconState;
 import com.android.systemui.statusbar.connectivity.MobileDataIndicators;
 import com.android.systemui.statusbar.connectivity.NetworkController;
 import com.android.systemui.statusbar.connectivity.SignalCallback;
@@ -78,7 +75,6 @@
     private QSCarrier[] mCarrierGroups = new QSCarrier[SIM_SLOTS];
     private int[] mLastSignalLevel = new int[SIM_SLOTS];
     private String[] mLastSignalLevelDescription = new String[SIM_SLOTS];
-    private final boolean mProviderModel;
     private final CarrierConfigTracker mCarrierConfigTracker;
 
     private boolean mIsSingleCarrier;
@@ -90,9 +86,6 @@
     private final SignalCallback mSignalCallback = new SignalCallback() {
                 @Override
                 public void setMobileDataIndicators(@NonNull MobileDataIndicators indicators) {
-                    if (mProviderModel) {
-                        return;
-                    }
                     int slotIndex = getSlotIndex(indicators.subId);
                     if (slotIndex >= SIM_SLOTS) {
                         Log.w(TAG, "setMobileDataIndicators - slot: " + slotIndex);
@@ -107,91 +100,12 @@
                             indicators.statusIcon.icon,
                             indicators.statusIcon.contentDescription,
                             indicators.typeContentDescription.toString(),
-                            indicators.roaming,
-                            mProviderModel
+                            indicators.roaming
                     );
                     mMainHandler.obtainMessage(H.MSG_UPDATE_STATE).sendToTarget();
                 }
 
                 @Override
-                public void setCallIndicator(@NonNull IconState statusIcon, int subId) {
-                    if (!mProviderModel) {
-                        return;
-                    }
-                    int slotIndex = getSlotIndex(subId);
-                    if (slotIndex >= SIM_SLOTS) {
-                        Log.w(TAG, "setMobileDataIndicators - slot: " + slotIndex);
-                        return;
-                    }
-                    if (slotIndex == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
-                        Log.e(TAG, "Invalid SIM slot index for subscription: " + subId);
-                        return;
-                    }
-
-                    boolean displayCallStrengthIcon =
-                            mCarrierConfigTracker.getCallStrengthConfig(subId);
-
-                    if (statusIcon.icon == R.drawable.ic_qs_no_calling_sms) {
-                        if (statusIcon.visible) {
-                            mInfos[slotIndex] = new CellSignalState(
-                                    true,
-                                    statusIcon.icon,
-                                    statusIcon.contentDescription,
-                                    "",
-                                    false,
-                                    mProviderModel);
-                        } else {
-                            // Whenever the no Calling & SMS state is cleared, switched to the last
-                            // known call strength icon.
-                            if (displayCallStrengthIcon) {
-                                mInfos[slotIndex] = new CellSignalState(
-                                        true,
-                                        mLastSignalLevel[slotIndex],
-                                        mLastSignalLevelDescription[slotIndex],
-                                        "",
-                                        false,
-                                        mProviderModel);
-                            } else {
-                                mInfos[slotIndex] = new CellSignalState(
-                                        true,
-                                        R.drawable.ic_qs_sim_card,
-                                        "",
-                                        "",
-                                        false,
-                                        mProviderModel);
-                            }
-                        }
-                        mMainHandler.obtainMessage(H.MSG_UPDATE_STATE).sendToTarget();
-                    } else {
-                        mLastSignalLevel[slotIndex] = statusIcon.icon;
-                        mLastSignalLevelDescription[slotIndex] = statusIcon.contentDescription;
-                        // Only Shows the call strength icon when the no Calling & SMS icon is not
-                        // shown.
-                        if (mInfos[slotIndex].mobileSignalIconId
-                                != R.drawable.ic_qs_no_calling_sms) {
-                            if (displayCallStrengthIcon) {
-                                mInfos[slotIndex] = new CellSignalState(
-                                        true,
-                                        statusIcon.icon,
-                                        statusIcon.contentDescription,
-                                        "",
-                                        false,
-                                        mProviderModel);
-                            } else {
-                                mInfos[slotIndex] = new CellSignalState(
-                                        true,
-                                        R.drawable.ic_qs_sim_card,
-                                        "",
-                                        "",
-                                        false,
-                                        mProviderModel);
-                            }
-                            mMainHandler.obtainMessage(H.MSG_UPDATE_STATE).sendToTarget();
-                        }
-                    }
-                }
-
-                @Override
                 public void setNoSims(boolean hasNoSims, boolean simDetected) {
                     if (hasNoSims) {
                         for (int i = 0; i < SIM_SLOTS; i++) {
@@ -219,14 +133,8 @@
             @Background Handler bgHandler, @Main Looper mainLooper,
             NetworkController networkController,
             CarrierTextManager.Builder carrierTextManagerBuilder, Context context,
-            CarrierConfigTracker carrierConfigTracker, FeatureFlags featureFlags,
-            SlotIndexResolver slotIndexResolver) {
+            CarrierConfigTracker carrierConfigTracker, SlotIndexResolver slotIndexResolver) {
 
-        if (featureFlags.isEnabled(Flags.COMBINED_STATUS_BAR_SIGNAL_ICONS)) {
-            mProviderModel = true;
-        } else {
-            mProviderModel = false;
-        }
         mActivityStarter = activityStarter;
         mBgHandler = bgHandler;
         mNetworkController = networkController;
@@ -262,8 +170,7 @@
                     R.drawable.ic_qs_no_calling_sms,
                     context.getText(AccessibilityContentDescriptions.NO_CALLING).toString(),
                     "",
-                    false,
-                    mProviderModel);
+                    false);
             mLastSignalLevel[i] = TelephonyIcons.MOBILE_CALL_STRENGTH_ICONS[0];
             mLastSignalLevelDescription[i] =
                     context.getText(AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0])
@@ -351,8 +258,7 @@
             for (int i = 0; i < SIM_SLOTS; i++) {
                 if (mInfos[i].visible
                         && mInfos[i].mobileSignalIconId == R.drawable.ic_qs_sim_card) {
-                    mInfos[i] = new CellSignalState(true, R.drawable.ic_blank, "", "", false,
-                            mProviderModel);
+                    mInfos[i] = new CellSignalState(true, R.drawable.ic_blank, "", "", false);
                 }
             }
         }
@@ -470,15 +376,13 @@
         private final CarrierTextManager.Builder mCarrierTextControllerBuilder;
         private final Context mContext;
         private final CarrierConfigTracker mCarrierConfigTracker;
-        private final FeatureFlags mFeatureFlags;
         private final SlotIndexResolver mSlotIndexResolver;
 
         @Inject
         public Builder(ActivityStarter activityStarter, @Background Handler handler,
                 @Main Looper looper, NetworkController networkController,
                 CarrierTextManager.Builder carrierTextControllerBuilder, Context context,
-                CarrierConfigTracker carrierConfigTracker, FeatureFlags featureFlags,
-                SlotIndexResolver slotIndexResolver) {
+                CarrierConfigTracker carrierConfigTracker, SlotIndexResolver slotIndexResolver) {
             mActivityStarter = activityStarter;
             mHandler = handler;
             mLooper = looper;
@@ -486,7 +390,6 @@
             mCarrierTextControllerBuilder = carrierTextControllerBuilder;
             mContext = context;
             mCarrierConfigTracker = carrierConfigTracker;
-            mFeatureFlags = featureFlags;
             mSlotIndexResolver = slotIndexResolver;
         }
 
@@ -498,7 +401,7 @@
         public QSCarrierGroupController build() {
             return new QSCarrierGroupController(mView, mActivityStarter, mHandler, mLooper,
                     mNetworkController, mCarrierTextControllerBuilder, mContext,
-                    mCarrierConfigTracker, mFeatureFlags, mSlotIndexResolver);
+                    mCarrierConfigTracker, mSlotIndexResolver);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index e52bfbd..d84b12c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -182,7 +182,7 @@
         for (int i = 1; i < mTiles.size() && mTiles.get(i) != null; i++) {
             newSpecs.add(mTiles.get(i).spec);
         }
-        host.changeTiles(mCurrentSpecs, newSpecs);
+        host.changeTilesByUser(mCurrentSpecs, newSpecs);
         mCurrentSpecs = newSpecs;
     }
 
@@ -200,7 +200,7 @@
     /** */
     public void resetTileSpecs(List<String> specs) {
         // Notify the host so the tiles get removed callbacks.
-        mHost.changeTiles(mCurrentSpecs, specs);
+        mHost.changeTilesByUser(mCurrentSpecs, specs);
         setTileSpecs(specs);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt b/packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt
index bd2f64b..6265b3c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt
@@ -73,6 +73,7 @@
             icon = tileData.icon?.loadDrawable(context)?.let {
                 QSTileImpl.DrawableIcon(it)
             } ?: ResourceIcon.get(R.drawable.android)
+            contentDescription = label
         }
         tile.onStateChanged(state)
         tile.post {
@@ -95,4 +96,4 @@
         val label: CharSequence,
         val icon: Icon?
     )
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
index bf565a8..cfc57db 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
@@ -289,7 +289,7 @@
                 }
             }
 
-            mServices.getHost().removeTile(component);
+            mServices.getHost().removeTile(CustomTile.toSpec(component));
         }
     };
 }
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/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
index f629a036..d5efe36 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
@@ -806,7 +806,8 @@
             return;
         }
 
-        mTelephonyManager.setDataEnabled(enabled);
+        mTelephonyManager.setDataEnabledForReason(
+                TelephonyManager.DATA_ENABLED_REASON_USER, enabled);
         if (disableOtherSubscriptions) {
             final List<SubscriptionInfo> subInfoList =
                     mSubscriptionManager.getActiveSubscriptionInfoList();
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/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 89a15f6..82de389 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -843,14 +843,20 @@
         // The media player creation is slow and needs on the background thread.
         return CallbackToFutureAdapter.getFuture((completer) -> {
             mBgExecutor.execute(() -> {
-                MediaPlayer player = MediaPlayer.create(mContext,
-                        Uri.fromFile(new File(mContext.getResources().getString(
-                                com.android.internal.R.string.config_cameraShutterSound))), null,
-                        new AudioAttributes.Builder()
-                                .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
-                                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
-                                .build(), AudioSystem.newAudioSessionId());
-                completer.set(player);
+                try {
+                    MediaPlayer player = MediaPlayer.create(mContext,
+                            Uri.fromFile(new File(mContext.getResources().getString(
+                                    com.android.internal.R.string.config_cameraShutterSound))),
+                            null,
+                            new AudioAttributes.Builder()
+                                    .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
+                                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+                                    .build(), AudioSystem.newAudioSessionId());
+                    completer.set(player);
+                } catch (IllegalStateException e) {
+                    Log.w(TAG, "Screenshot sound initialization failed", e);
+                    completer.set(null);
+                }
             });
             return "ScreenshotController#loadCameraSound";
         });
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/shade/CombinedShadeHeadersConstraintManager.kt b/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManager.kt
new file mode 100644
index 0000000..e360ec2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManager.kt
@@ -0,0 +1,79 @@
+/*
+ * 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.shade
+
+import androidx.constraintlayout.widget.ConstraintSet
+
+typealias ConstraintChange = ConstraintSet.() -> Unit
+
+operator fun ConstraintChange?.plus(other: ConstraintChange?): ConstraintChange? {
+    // Prevent wrapping
+    if (this == null) return other
+    if (other == null) return this
+    else return {
+        this@plus()
+        other()
+    }
+}
+
+/**
+ * Contains all changes that need to be performed to the different [ConstraintSet] in
+ * [LargeScreenShadeHeaderController].
+ */
+data class ConstraintsChanges(
+    val qqsConstraintsChanges: ConstraintChange? = null,
+    val qsConstraintsChanges: ConstraintChange? = null,
+    val largeScreenConstraintsChanges: ConstraintChange? = null
+) {
+    operator fun plus(other: ConstraintsChanges) = ConstraintsChanges(
+        qqsConstraintsChanges + other.qqsConstraintsChanges,
+        qsConstraintsChanges + other.qsConstraintsChanges,
+        largeScreenConstraintsChanges + other.largeScreenConstraintsChanges
+    )
+}
+
+/**
+ * Determines [ConstraintChanges] for [LargeScreenShadeHeaderController] based on configurations.
+ *
+ * Given that the number of different scenarios is not that large, having specific methods instead
+ * of a full map between state and [ConstraintSet] was preferred.
+ */
+interface CombinedShadeHeadersConstraintManager {
+    /**
+     * Changes for when the visibility of the privacy chip changes
+     */
+    fun privacyChipVisibilityConstraints(visible: Boolean): ConstraintsChanges
+
+    /**
+     * Changes for situations with no top center cutout (there may be a corner cutout)
+     */
+    fun emptyCutoutConstraints(): ConstraintsChanges
+
+    /**
+     * Changes to incorporate side insets due to rounded corners/corner cutouts
+     */
+    fun edgesGuidelinesConstraints(
+        cutoutStart: Int,
+        paddingStart: Int,
+        cutoutEnd: Int,
+        paddingEnd: Int
+    ): ConstraintsChanges
+
+    /**
+     * Changes for situations with top center cutout (in this case, there are no corner cutouts).
+     */
+    fun centerCutoutConstraints(rtl: Boolean, offsetFromEdge: Int): ConstraintsChanges
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
new file mode 100644
index 0000000..4063af3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
@@ -0,0 +1,109 @@
+/*
+ * 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.shade
+
+import android.view.ViewGroup
+import androidx.constraintlayout.widget.ConstraintSet
+import com.android.systemui.R
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
+
+/**
+ * Standard implementation of [CombinedShadeHeadersConstraintManager].
+ */
+@CentralSurfacesComponent.CentralSurfacesScope
+object CombinedShadeHeadersConstraintManagerImpl : CombinedShadeHeadersConstraintManager {
+
+    override fun privacyChipVisibilityConstraints(visible: Boolean): ConstraintsChanges {
+        val constraintAlpha = if (visible) 0f else 1f
+        return ConstraintsChanges(
+            qqsConstraintsChanges = {
+                setAlpha(R.id.statusIcons, constraintAlpha)
+                setAlpha(R.id.batteryRemainingIcon, constraintAlpha)
+            }
+        )
+    }
+
+    override fun emptyCutoutConstraints(): ConstraintsChanges {
+        return ConstraintsChanges(
+            qqsConstraintsChanges = {
+                connect(R.id.date, ConstraintSet.END, R.id.barrier, ConstraintSet.START)
+                createBarrier(
+                    R.id.barrier,
+                    ConstraintSet.START,
+                    0,
+                    R.id.statusIcons,
+                    R.id.privacy_container
+                )
+                connect(R.id.statusIcons, ConstraintSet.START, R.id.date, ConstraintSet.END)
+                connect(R.id.privacy_container, ConstraintSet.START, R.id.date, ConstraintSet.END)
+                constrainWidth(R.id.statusIcons, ViewGroup.LayoutParams.WRAP_CONTENT)
+            }
+        )
+    }
+
+    override fun edgesGuidelinesConstraints(
+        cutoutStart: Int,
+        paddingStart: Int,
+        cutoutEnd: Int,
+        paddingEnd: Int
+    ): ConstraintsChanges {
+        val change: ConstraintChange = {
+            setGuidelineBegin(R.id.begin_guide, Math.max(cutoutStart - paddingStart, 0))
+            setGuidelineEnd(R.id.end_guide, Math.max(cutoutEnd - paddingEnd, 0))
+        }
+        return ConstraintsChanges(
+            qqsConstraintsChanges = change,
+            qsConstraintsChanges = change
+        )
+    }
+
+    override fun centerCutoutConstraints(rtl: Boolean, offsetFromEdge: Int): ConstraintsChanges {
+        val centerStart = if (!rtl) R.id.center_left else R.id.center_right
+        val centerEnd = if (!rtl) R.id.center_right else R.id.center_left
+        // Use guidelines to block the center cutout area.
+        return ConstraintsChanges(
+            qqsConstraintsChanges = {
+                setGuidelineBegin(centerStart, offsetFromEdge)
+                setGuidelineEnd(centerEnd, offsetFromEdge)
+                connect(R.id.date, ConstraintSet.END, centerStart, ConstraintSet.START)
+                connect(
+                    R.id.statusIcons,
+                    ConstraintSet.START,
+                    centerEnd,
+                    ConstraintSet.END
+                )
+                connect(
+                    R.id.privacy_container,
+                    ConstraintSet.START,
+                    centerEnd,
+                    ConstraintSet.END
+                )
+                constrainWidth(R.id.statusIcons, 0)
+            },
+            qsConstraintsChanges = {
+                setGuidelineBegin(centerStart, offsetFromEdge)
+                setGuidelineEnd(centerEnd, offsetFromEdge)
+                connect(
+                    R.id.privacy_container,
+                    ConstraintSet.START,
+                    centerEnd,
+                    ConstraintSet.END
+                )
+            }
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
new file mode 100644
index 0000000..5793105
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
@@ -0,0 +1,510 @@
+/*
+ * 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.annotation.IdRes
+import android.app.StatusBarManager
+import android.content.res.Configuration
+import android.os.Trace
+import android.os.Trace.TRACE_TAG_APP
+import android.util.Pair
+import android.view.View
+import android.view.WindowInsets
+import android.widget.TextView
+import androidx.annotation.VisibleForTesting
+import androidx.constraintlayout.motion.widget.MotionLayout
+import com.android.settingslib.Utils
+import com.android.systemui.Dumpable
+import com.android.systemui.R
+import com.android.systemui.animation.ShadeInterpolation
+import com.android.systemui.battery.BatteryMeterView
+import com.android.systemui.battery.BatteryMeterViewController
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.qs.ChipVisibilityListener
+import com.android.systemui.qs.HeaderPrivacyIconsController
+import com.android.systemui.qs.carrier.QSCarrierGroup
+import com.android.systemui.qs.carrier.QSCarrierGroupController
+import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.HEADER_TRANSITION_ID
+import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.LARGE_SCREEN_HEADER_CONSTRAINT
+import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.LARGE_SCREEN_HEADER_TRANSITION_ID
+import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QQS_HEADER_CONSTRAINT
+import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QS_HEADER_CONSTRAINT
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
+import com.android.systemui.statusbar.phone.StatusBarIconController
+import com.android.systemui.statusbar.phone.StatusIconContainer
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
+import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.LARGE_SCREEN_BATTERY_CONTROLLER
+import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.LARGE_SCREEN_SHADE_HEADER
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.VariableDateView
+import com.android.systemui.statusbar.policy.VariableDateViewController
+import com.android.systemui.util.ViewController
+import java.io.PrintWriter
+import javax.inject.Inject
+import javax.inject.Named
+
+/**
+ * Controller for QS header on Large Screen width (large screen + landscape).
+ *
+ * Additionally, this serves as the staging ground for the combined QS headers. A single
+ * [MotionLayout] that changes constraints depending on the configuration and can animate the
+ * expansion of the headers in small screen portrait.
+ *
+ * [header] will be a [MotionLayout] if [Flags.COMBINED_QS_HEADERS] is enabled. In this case, the
+ * [MotionLayout] has 2 transitions:
+ * * [HEADER_TRANSITION_ID]: [QQS_HEADER_CONSTRAINT] <-> [QS_HEADER_CONSTRAINT] for portrait
+ *   handheld device configuration.
+ * * [LARGE_SCREEN_HEADER_TRANSITION_ID]: [LARGE_SCREEN_HEADER_CONSTRAINT] (to itself) for all
+ *   other configurations
+ */
+@CentralSurfacesScope
+class LargeScreenShadeHeaderController @Inject constructor(
+    @Named(LARGE_SCREEN_SHADE_HEADER) private val header: View,
+    private val statusBarIconController: StatusBarIconController,
+    private val privacyIconsController: HeaderPrivacyIconsController,
+    private val insetsProvider: StatusBarContentInsetsProvider,
+    private val configurationController: ConfigurationController,
+    private val variableDateViewControllerFactory: VariableDateViewController.Factory,
+    @Named(LARGE_SCREEN_BATTERY_CONTROLLER)
+    private val batteryMeterViewController: BatteryMeterViewController,
+    private val dumpManager: DumpManager,
+    private val featureFlags: FeatureFlags,
+    private val qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder,
+    private val combinedShadeHeadersConstraintManager: CombinedShadeHeadersConstraintManager
+) : ViewController<View>(header), Dumpable {
+
+    companion object {
+        /** IDs for transitions and constraints for the [MotionLayout]. These are only used when
+         * [Flags.COMBINED_QS_HEADERS] is enabled.
+         */
+        @VisibleForTesting
+        internal val HEADER_TRANSITION_ID = R.id.header_transition
+        @VisibleForTesting
+        internal val LARGE_SCREEN_HEADER_TRANSITION_ID = R.id.large_screen_header_transition
+        @VisibleForTesting
+        internal val QQS_HEADER_CONSTRAINT = R.id.qqs_header_constraint
+        @VisibleForTesting
+        internal val QS_HEADER_CONSTRAINT = R.id.qs_header_constraint
+        @VisibleForTesting
+        internal val LARGE_SCREEN_HEADER_CONSTRAINT = R.id.large_screen_header_constraint
+
+        private fun Int.stateToString() = when (this) {
+            QQS_HEADER_CONSTRAINT -> "QQS Header"
+            QS_HEADER_CONSTRAINT -> "QS Header"
+            LARGE_SCREEN_HEADER_CONSTRAINT -> "Large Screen Header"
+            else -> "Unknown state"
+        }
+    }
+
+    init {
+        loadConstraints()
+    }
+
+    private val combinedHeaders = featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)
+
+    private lateinit var iconManager: StatusBarIconController.TintedIconManager
+    private lateinit var carrierIconSlots: List<String>
+    private lateinit var qsCarrierGroupController: QSCarrierGroupController
+
+    private val batteryIcon: BatteryMeterView = header.findViewById(R.id.batteryRemainingIcon)
+    private val clock: TextView = header.findViewById(R.id.clock)
+    private val date: TextView = header.findViewById(R.id.date)
+    private val iconContainer: StatusIconContainer = header.findViewById(R.id.statusIcons)
+    private val qsCarrierGroup: QSCarrierGroup = header.findViewById(R.id.carrier_group)
+
+    private var cutoutLeft = 0
+    private var cutoutRight = 0
+    private var roundedCorners = 0
+    private var lastInsets: WindowInsets? = null
+
+    private var qsDisabled = false
+    private var visible = false
+        set(value) {
+            if (field == value) {
+                return
+            }
+            field = value
+            updateListeners()
+        }
+
+    /**
+     * Whether the QQS/QS part of the shade is visible. This is particularly important in
+     * Lockscreen, as the shade is visible but QS is not.
+     */
+    var qsVisible = false
+        set(value) {
+            if (field == value) {
+                return
+            }
+            field = value
+            onShadeExpandedChanged()
+        }
+
+    /**
+     * Whether we are in a configuration with large screen width. In this case, the header is a
+     * single line.
+     */
+    var largeScreenActive = false
+        set(value) {
+            if (field == value) {
+                return
+            }
+            field = value
+            onHeaderStateChanged()
+        }
+
+    /**
+     * Expansion fraction of the QQS/QS shade. This is not the expansion between QQS <-> QS.
+     */
+    var shadeExpandedFraction = -1f
+        set(value) {
+            if (visible && field != value) {
+                header.alpha = ShadeInterpolation.getContentAlpha(value)
+                field = value
+            }
+        }
+
+    /**
+     * Expansion fraction of the QQS <-> QS animation.
+     */
+    var qsExpandedFraction = -1f
+        set(value) {
+            if (visible && field != value) {
+                field = value
+                updatePosition()
+            }
+        }
+
+    /**
+     * Current scroll of QS.
+     */
+    var qsScrollY = 0
+        set(value) {
+            if (field != value) {
+                field = value
+                updateScrollY()
+            }
+        }
+
+    private val insetListener = View.OnApplyWindowInsetsListener { view, insets ->
+        updateConstraintsForInsets(view as MotionLayout, insets)
+        lastInsets = WindowInsets(insets)
+
+        view.onApplyWindowInsets(insets)
+    }
+
+    private val chipVisibilityListener: ChipVisibilityListener = object : ChipVisibilityListener {
+        override fun onChipVisibilityRefreshed(visible: Boolean) {
+            if (header is MotionLayout) {
+                // If the privacy chip is visible, we hide the status icons and battery remaining
+                // icon, only in QQS.
+                val update = combinedShadeHeadersConstraintManager
+                    .privacyChipVisibilityConstraints(visible)
+                header.updateAllConstraints(update)
+            }
+        }
+    }
+
+    private val configurationControllerListener =
+        object : ConfigurationController.ConfigurationListener {
+        override fun onConfigChanged(newConfig: Configuration?) {
+            if (header !is MotionLayout) {
+                val left = header.resources.getDimensionPixelSize(
+                    R.dimen.large_screen_shade_header_left_padding
+                )
+                header.setPadding(
+                    left,
+                    header.paddingTop,
+                    header.paddingRight,
+                    header.paddingBottom
+                )
+            }
+        }
+
+        override fun onDensityOrFontScaleChanged() {
+            clock.setTextAppearance(R.style.TextAppearance_QS_Status)
+            date.setTextAppearance(R.style.TextAppearance_QS_Status)
+            qsCarrierGroup.updateTextAppearance(R.style.TextAppearance_QS_Status_Carriers)
+            if (header is MotionLayout) {
+                loadConstraints()
+                lastInsets?.let { updateConstraintsForInsets(header, it) }
+            }
+            updateResources()
+        }
+    }
+
+    override fun onInit() {
+        if (header is MotionLayout) {
+            variableDateViewControllerFactory.create(date as VariableDateView).init()
+        }
+        batteryMeterViewController.init()
+
+        // battery settings same as in QS icons
+        batteryMeterViewController.ignoreTunerUpdates()
+        batteryIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE)
+
+        iconManager = StatusBarIconController.TintedIconManager(iconContainer, featureFlags)
+        iconManager.setTint(
+            Utils.getColorAttrDefaultColor(header.context, android.R.attr.textColorPrimary)
+        )
+
+        carrierIconSlots = if (featureFlags.isEnabled(Flags.COMBINED_STATUS_BAR_SIGNAL_ICONS)) {
+            listOf(
+                header.context.getString(com.android.internal.R.string.status_bar_no_calling),
+                header.context.getString(com.android.internal.R.string.status_bar_call_strength)
+            )
+        } else {
+            listOf(header.context.getString(com.android.internal.R.string.status_bar_mobile))
+        }
+        qsCarrierGroupController = qsCarrierGroupControllerBuilder
+            .setQSCarrierGroup(qsCarrierGroup)
+            .build()
+    }
+
+    override fun onViewAttached() {
+        privacyIconsController.chipVisibilityListener = chipVisibilityListener
+        if (header is MotionLayout) {
+            header.setOnApplyWindowInsetsListener(insetListener)
+            clock.addOnLayoutChangeListener { v, _, _, _, _, _, _, _, _ ->
+                val newPivot = if (v.isLayoutRtl) v.width.toFloat() else 0f
+                v.pivotX = newPivot
+            }
+        }
+
+        dumpManager.registerDumpable(this)
+        configurationController.addCallback(configurationControllerListener)
+
+        updateVisibility()
+        updateTransition()
+    }
+
+    override fun onViewDetached() {
+        privacyIconsController.chipVisibilityListener = null
+        dumpManager.unregisterDumpable(this::class.java.simpleName)
+        configurationController.removeCallback(configurationControllerListener)
+    }
+
+    fun disable(state1: Int, state2: Int, animate: Boolean) {
+        val disabled = state2 and StatusBarManager.DISABLE2_QUICK_SETTINGS != 0
+        if (disabled == qsDisabled) return
+        qsDisabled = disabled
+        updateVisibility()
+    }
+
+    private fun loadConstraints() {
+        if (header is MotionLayout) {
+            // Use resources.getXml instead of passing the resource id due to bug b/205018300
+            header.getConstraintSet(QQS_HEADER_CONSTRAINT)
+                .load(context, resources.getXml(R.xml.qqs_header))
+            val qsConstraints = if (featureFlags.isEnabled(Flags.NEW_HEADER)) {
+                R.xml.qs_header_new
+            } else {
+                R.xml.qs_header
+            }
+            header.getConstraintSet(QS_HEADER_CONSTRAINT)
+                .load(context, resources.getXml(qsConstraints))
+            header.getConstraintSet(LARGE_SCREEN_HEADER_CONSTRAINT)
+                .load(context, resources.getXml(R.xml.large_screen_shade_header))
+        }
+    }
+
+    private fun updateConstraintsForInsets(view: MotionLayout, insets: WindowInsets) {
+        val cutout = insets.displayCutout
+
+        val sbInsets: Pair<Int, Int> = insetsProvider.getStatusBarContentInsetsForCurrentRotation()
+        cutoutLeft = sbInsets.first
+        cutoutRight = sbInsets.second
+        val hasCornerCutout: Boolean = insetsProvider.currentRotationHasCornerCutout()
+        updateQQSPaddings()
+        // Set these guides as the left/right limits for content that lives in the top row, using
+        // cutoutLeft and cutoutRight
+        var changes = combinedShadeHeadersConstraintManager
+            .edgesGuidelinesConstraints(
+                if (view.isLayoutRtl) cutoutRight else cutoutLeft,
+                header.paddingStart,
+                if (view.isLayoutRtl) cutoutLeft else cutoutRight,
+                header.paddingEnd
+            )
+
+        if (cutout != null) {
+            val topCutout = cutout.boundingRectTop
+            if (topCutout.isEmpty || hasCornerCutout) {
+                changes += combinedShadeHeadersConstraintManager.emptyCutoutConstraints()
+            } else {
+                changes += combinedShadeHeadersConstraintManager.centerCutoutConstraints(
+                    view.isLayoutRtl,
+                    (view.width - view.paddingLeft - view.paddingRight - topCutout.width()) / 2
+                )
+            }
+        } else {
+           changes += combinedShadeHeadersConstraintManager.emptyCutoutConstraints()
+        }
+
+        view.updateAllConstraints(changes)
+    }
+
+    private fun updateScrollY() {
+        if (!largeScreenActive && combinedHeaders) {
+            header.scrollY = qsScrollY
+        }
+    }
+
+    private fun onShadeExpandedChanged() {
+        if (qsVisible) {
+            privacyIconsController.startListening()
+        } else {
+            privacyIconsController.stopListening()
+        }
+        updateVisibility()
+        updatePosition()
+    }
+
+    private fun onHeaderStateChanged() {
+        if (largeScreenActive || combinedHeaders) {
+            privacyIconsController.onParentVisible()
+        } else {
+            privacyIconsController.onParentInvisible()
+        }
+        updateVisibility()
+        updateTransition()
+    }
+
+    /**
+     * If not using [combinedHeaders] this should only be visible on large screen. Else, it should
+     * be visible any time the QQS/QS shade is open.
+     */
+    private fun updateVisibility() {
+        val visibility = if (!largeScreenActive && !combinedHeaders || qsDisabled) {
+            View.GONE
+        } else if (qsVisible) {
+            View.VISIBLE
+        } else {
+            View.INVISIBLE
+        }
+        if (header.visibility != visibility) {
+            header.visibility = visibility
+            visible = visibility == View.VISIBLE
+        }
+    }
+
+    private fun updateTransition() {
+        if (!combinedHeaders) {
+            return
+        }
+        header as MotionLayout
+        if (largeScreenActive) {
+            header.setTransition(LARGE_SCREEN_HEADER_TRANSITION_ID)
+            header.getConstraintSet(LARGE_SCREEN_HEADER_CONSTRAINT).applyTo(header)
+        } else {
+            header.setTransition(HEADER_TRANSITION_ID)
+            header.transitionToStart()
+            updatePosition()
+            updateScrollY()
+        }
+    }
+
+    private fun updatePosition() {
+        if (header is MotionLayout && !largeScreenActive && visible) {
+            Trace.instantForTrack(
+                TRACE_TAG_APP,
+                "LargeScreenHeaderController - updatePosition",
+                "position: $qsExpandedFraction"
+            )
+            header.progress = qsExpandedFraction
+        }
+    }
+
+    private fun updateListeners() {
+        qsCarrierGroupController.setListening(visible)
+        if (visible) {
+            updateSingleCarrier(qsCarrierGroupController.isSingleCarrier)
+            qsCarrierGroupController.setOnSingleCarrierChangedListener { updateSingleCarrier(it) }
+            statusBarIconController.addIconGroup(iconManager)
+        } else {
+            qsCarrierGroupController.setOnSingleCarrierChangedListener(null)
+            statusBarIconController.removeIconGroup(iconManager)
+        }
+    }
+
+    private fun updateSingleCarrier(singleCarrier: Boolean) {
+        if (singleCarrier) {
+            iconContainer.removeIgnoredSlots(carrierIconSlots)
+        } else {
+            iconContainer.addIgnoredSlots(carrierIconSlots)
+        }
+    }
+
+    private fun updateResources() {
+        roundedCorners = resources.getDimensionPixelSize(R.dimen.rounded_corner_content_padding)
+        val padding = resources.getDimensionPixelSize(R.dimen.qs_panel_padding)
+        header.setPadding(padding, header.paddingTop, padding, header.paddingBottom)
+        updateQQSPaddings()
+    }
+
+    private fun updateQQSPaddings() {
+        if (header is MotionLayout) {
+            val clockPaddingStart = resources
+                .getDimensionPixelSize(R.dimen.status_bar_left_clock_starting_padding)
+            val clockPaddingEnd = resources
+                .getDimensionPixelSize(R.dimen.status_bar_left_clock_end_padding)
+            clock.setPaddingRelative(
+                clockPaddingStart,
+                clock.paddingTop,
+                clockPaddingEnd,
+                clock.paddingBottom
+            )
+        }
+    }
+
+    override fun dump(pw: PrintWriter, args: Array<out String>) {
+        pw.println("visible: $visible")
+        pw.println("shadeExpanded: $qsVisible")
+        pw.println("shadeExpandedFraction: $shadeExpandedFraction")
+        pw.println("active: $largeScreenActive")
+        pw.println("qsExpandedFraction: $qsExpandedFraction")
+        pw.println("qsScrollY: $qsScrollY")
+        if (combinedHeaders) {
+            header as MotionLayout
+            pw.println("currentState: ${header.currentState.stateToString()}")
+        }
+    }
+
+    private fun MotionLayout.updateConstraints(@IdRes state: Int, update: ConstraintChange) {
+        val constraints = getConstraintSet(state)
+        constraints.update()
+        updateState(state, constraints)
+    }
+
+    /**
+     * Updates the [ConstraintSet] for the case of combined headers.
+     *
+     * Only non-`null` changes are applied to reduce the number of rebuilding in the [MotionLayout].
+     */
+    private fun MotionLayout.updateAllConstraints(updates: ConstraintsChanges) {
+        if (updates.qqsConstraintsChanges != null) {
+            updateConstraints(QQS_HEADER_CONSTRAINT, updates.qqsConstraintsChanges)
+        }
+        if (updates.qsConstraintsChanges != null) {
+            updateConstraints(QS_HEADER_CONSTRAINT, updates.qsConstraintsChanges)
+        }
+        if (updates.largeScreenConstraintsChanges != null) {
+            updateConstraints(LARGE_SCREEN_HEADER_CONSTRAINT, updates.largeScreenConstraintsChanges)
+        }
+    }
+}
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 92%
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..9818af3 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,7 @@
 import android.util.AttributeSet;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.TapAgainView;
 
 public class NotificationPanelView extends PanelView {
 
@@ -35,8 +36,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 98%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
rename to packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index dcc02b4..24448bb 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;
 
@@ -140,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;
@@ -176,12 +177,32 @@
 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.LockscreenGestureLogger;
 import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
+import com.android.systemui.statusbar.phone.NotificationIconAreaController;
+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;
@@ -1009,6 +1030,7 @@
         }
 
         mTapAgainViewController.init();
+        mLargeScreenShadeHeaderController.init();
         mKeyguardUnfoldTransition.ifPresent(u -> u.setup(mView));
         mNotificationPanelUnfoldAnimationController.ifPresent(controller ->
                 controller.setup(mNotificationContainerParent));
@@ -1107,7 +1129,7 @@
                 SystemBarUtils.getQuickQsOffsetHeight(mView.getContext());
         int topMargin = mUseLargeScreenShadeHeader ? mLargeScreenShadeHeaderHeight :
                 mResources.getDimensionPixelSize(R.dimen.notification_panel_margin_top);
-        mLargeScreenShadeHeaderController.setActive(mUseLargeScreenShadeHeader);
+        mLargeScreenShadeHeaderController.setLargeScreenActive(mUseLargeScreenShadeHeader);
         mAmbientState.setStackTopMargin(topMargin);
         mNotificationsQSContainerController.updateResources();
 
@@ -1667,18 +1689,30 @@
         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.
+     * If in split shade, it will collapse the whole shade.
      *
      * @param animateAway Do not stop when QS becomes QQS. Fling until QS isn't visible anymore.
      */
     public void animateCloseQs(boolean animateAway) {
+        if (mSplitShadeEnabled) {
+            collapsePanel(
+                    /* animate= */true, /* delayed= */false, /* speedUpFactor= */1.0f);
+            return;
+        }
+
         if (mQsExpansionAnimator != null) {
             if (!mQsAnimatorExpand) {
                 return;
@@ -2376,7 +2410,7 @@
                 : getExpandedFraction();
         mLargeScreenShadeHeaderController.setShadeExpandedFraction(shadeExpandedFraction);
         mLargeScreenShadeHeaderController.setQsExpandedFraction(qsExpansionFraction);
-        mLargeScreenShadeHeaderController.setShadeExpanded(mQsVisible);
+        mLargeScreenShadeHeaderController.setQsVisible(mQsVisible);
     }
 
     private void onStackYChanged(boolean shouldAnimate) {
@@ -2965,7 +2999,7 @@
     }
 
     @Override
-    protected int getMaxPanelHeight() {
+    public int getMaxPanelHeight() {
         int min = mStatusBarMinHeight;
         if (!(mBarState == KEYGUARD)
                 && mNotificationStackScrollLayoutController.getNotGoneChildCount() == 0) {
@@ -3069,12 +3103,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();
@@ -3183,14 +3219,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);
     }
 
@@ -3356,19 +3385,11 @@
         return mQsExpanded;
     }
 
-    public boolean isQsDetailShowing() {
-        return mQs.isShowingDetail();
-    }
-
     /** Returns whether the QS customizer is currently active. */
     public boolean isQsCustomizing() {
         return mQs.isCustomizing();
     }
 
-    public void closeQsDetail() {
-        mQs.closeDetail();
-    }
-
     /** Close the QS customizer if it is open. */
     public void closeQsCustomizer() {
         mQs.closeCustomizer();
@@ -3712,6 +3733,8 @@
 
         final float dozeAmount = dozing ? 1 : 0;
         mStatusBarStateController.setAndInstrumentDozeAmount(mView, dozeAmount, animate);
+
+        updateKeyguardStatusViewAlignment(animate);
     }
 
     public void setPulsing(boolean pulsing) {
@@ -3908,7 +3931,6 @@
      * {@link ShadeViewManager}.
      */
     public void updateNotificationViews(String reason) {
-        mNotificationStackScrollLayoutController.updateSectionBoundaries(reason);
         mNotificationStackScrollLayoutController.updateFooter();
 
         mNotificationIconAreaController.updateNotificationIcons(createVisibleEntriesList());
@@ -4865,6 +4887,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) {
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..7dc9dc7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/OWNERS
@@ -0,0 +1,14 @@
+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 *ShadeHeader* = 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/PanelView.java b/packages/SystemUI/src/com/android/systemui/shade/PanelView.java
similarity index 91%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
rename to packages/SystemUI/src/com/android/systemui/shade/PanelView.java
index 45dc943..1082967 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/PanelView.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.content.res.Configuration;
@@ -22,6 +22,10 @@
 import android.view.MotionEvent;
 import android.widget.FrameLayout;
 
+import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
+
 public abstract class PanelView extends FrameLayout {
     public static final boolean DEBUG = false;
     public static final String TAG = PanelView.class.getSimpleName();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/PanelViewController.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
rename to packages/SystemUI/src/com/android/systemui/shade/PanelViewController.java
index d2fc1af..229acf4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/PanelViewController.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.shade;
 
 import static android.view.View.INVISIBLE;
 import static android.view.View.VISIBLE;
@@ -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;
 
@@ -59,13 +60,21 @@
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.notification.stack.AmbientState;
+import com.android.systemui.statusbar.phone.BounceInterpolator;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
+import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
 import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.time.SystemClock;
 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;
@@ -386,7 +395,7 @@
         return Math.abs(yDiff) >= Math.abs(xDiff);
     }
 
-    protected void startExpandMotion(float newX, float newY, boolean startTracking,
+    public void startExpandMotion(float newX, float newY, boolean startTracking,
             float expandedHeight) {
         if (!mHandlingPointerUp && !mStatusBarStateController.isDozing()) {
             beginJankMonitoring(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
@@ -599,9 +608,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 +724,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 +1041,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 +1120,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/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/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index e1e2de50..f4ca7ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -125,7 +125,7 @@
                 updateLockscreenNotificationSetting();
                 getEntryManager().updateNotifications("ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED");
                 // TODO(b/231976036): Consolidate pipeline invalidations related to this event
-                notifyNotificationStateChanged();
+                // notifyNotificationStateChanged();
             }
         }
     };
@@ -271,7 +271,7 @@
                     getEntryManager().updateNotifications("LOCK_SCREEN_ALLOW_REMOTE_INPUT"
                             + " or ZEN_MODE change");
                     // TODO(b/231976036): Consolidate pipeline invalidations related to this event
-                    notifyNotificationStateChanged();
+                    // notifyNotificationStateChanged();
                 }
             }
         };
@@ -642,6 +642,8 @@
         //   - device keyguard is shown in secure mode;
         //   - profile is locked with a work challenge.
         SparseArray<UserInfo> currentProfiles = getCurrentProfiles();
+        SparseBooleanArray oldPublicModes = mLockscreenPublicMode.clone();
+        SparseBooleanArray oldWorkChallenges = mUsersWithSeparateWorkChallenge.clone();
         mUsersWithSeparateWorkChallenge.clear();
         for (int i = currentProfiles.size() - 1; i >= 0; i--) {
             final int userId = currentProfiles.valueAt(i).id;
@@ -660,7 +662,10 @@
         }
         getEntryManager().updateNotifications("NotificationLockscreenUserManager.updatePublicMode");
         // TODO(b/234738798): Migrate KeyguardNotificationVisibilityProvider to use this listener
-        notifyNotificationStateChanged();
+        if (!mLockscreenPublicMode.equals(oldPublicModes)
+                || !mUsersWithSeparateWorkChallenge.equals(oldWorkChallenges)) {
+            notifyNotificationStateChanged();
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java
index f2014e9..ec221b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java
@@ -26,25 +26,17 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.provider.Settings.Global;
-import android.telephony.AccessNetworkConstants;
 import android.telephony.CellSignalStrength;
 import android.telephony.CellSignalStrengthCdma;
-import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
-import android.telephony.ims.ImsException;
-import android.telephony.ims.ImsMmTelManager;
-import android.telephony.ims.ImsReasonInfo;
-import android.telephony.ims.ImsRegistrationAttributes;
-import android.telephony.ims.RegistrationManager.RegistrationCallback;
 import android.text.Html;
 import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.settingslib.AccessibilityContentDescriptions;
 import com.android.settingslib.SignalIcon.MobileIconGroup;
 import com.android.settingslib.graph.SignalDrawable;
 import com.android.settingslib.mobile.MobileMappings.Config;
@@ -54,8 +46,6 @@
 import com.android.settingslib.mobile.TelephonyIcons;
 import com.android.settingslib.net.SignalStrengthUtil;
 import com.android.systemui.R;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.util.CarrierConfigTracker;
 
 import java.io.PrintWriter;
@@ -70,33 +60,22 @@
 public class MobileSignalController extends SignalController<MobileState, MobileIconGroup> {
     private static final SimpleDateFormat SSDF = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
     private static final int STATUS_HISTORY_SIZE = 64;
-    private static final int IMS_TYPE_WWAN = 1;
-    private static final int IMS_TYPE_WLAN = 2;
-    private static final int IMS_TYPE_WLAN_CROSS_SIM = 3;
     private final TelephonyManager mPhone;
     private final CarrierConfigTracker mCarrierConfigTracker;
-    private final ImsMmTelManager mImsMmTelManager;
     private final SubscriptionDefaults mDefaults;
     private final String mNetworkNameDefault;
     private final String mNetworkNameSeparator;
     private final ContentObserver mObserver;
-    private final boolean mProviderModelBehavior;
-    private final Handler mReceiverHandler;
-    private int mImsType = IMS_TYPE_WWAN;
     // Save entire info for logging, we only use the id.
     final SubscriptionInfo mSubscriptionInfo;
     private Map<String, MobileIconGroup> mNetworkToIconLookup;
 
-    private int mLastLevel;
     private MobileIconGroup mDefaultIcons;
     private Config mConfig;
     @VisibleForTesting
     boolean mInflateSignalStrengths = false;
-    private int mLastWwanLevel;
-    private int mLastWlanLevel;
-    private int mLastWlanCrossSimLevel;
     @VisibleForTesting
-    MobileStatusTracker mMobileStatusTracker;
+    final MobileStatusTracker mMobileStatusTracker;
 
     // Save the previous STATUS_HISTORY_SIZE states for logging.
     private final String[] mMobileStatusHistory = new String[STATUS_HISTORY_SIZE];
@@ -133,52 +112,6 @@
                 }
             };
 
-    private final RegistrationCallback mRegistrationCallback = new RegistrationCallback() {
-        @Override
-        public void onRegistered(ImsRegistrationAttributes attributes) {
-            Log.d(mTag, "onRegistered: " + "attributes=" + attributes);
-            int imsTransportType = attributes.getTransportType();
-            int registrationAttributes = attributes.getAttributeFlags();
-            if (imsTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
-                mImsType = IMS_TYPE_WWAN;
-                IconState statusIcon = new IconState(
-                        true,
-                        getCallStrengthIcon(mLastWwanLevel, /* isWifi= */false),
-                        getCallStrengthDescription(mLastWwanLevel, /* isWifi= */false));
-                notifyCallStateChange(statusIcon, mSubscriptionInfo.getSubscriptionId());
-            } else if (imsTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
-                if (registrationAttributes == 0) {
-                    mImsType = IMS_TYPE_WLAN;
-                    IconState statusIcon = new IconState(
-                            true,
-                            getCallStrengthIcon(mLastWlanLevel, /* isWifi= */true),
-                            getCallStrengthDescription(mLastWlanLevel, /* isWifi= */true));
-                    notifyCallStateChange(statusIcon, mSubscriptionInfo.getSubscriptionId());
-                } else if (registrationAttributes
-                        == ImsRegistrationAttributes.ATTR_EPDG_OVER_CELL_INTERNET) {
-                    mImsType = IMS_TYPE_WLAN_CROSS_SIM;
-                    IconState statusIcon = new IconState(
-                            true,
-                            getCallStrengthIcon(mLastWlanCrossSimLevel, /* isWifi= */false),
-                            getCallStrengthDescription(
-                                    mLastWlanCrossSimLevel, /* isWifi= */false));
-                    notifyCallStateChange(statusIcon, mSubscriptionInfo.getSubscriptionId());
-                }
-            }
-        }
-
-        @Override
-        public void onUnregistered(ImsReasonInfo info) {
-            Log.d(mTag, "onDeregistered: " + "info=" + info);
-            mImsType = IMS_TYPE_WWAN;
-            IconState statusIcon = new IconState(
-                    true,
-                    getCallStrengthIcon(mLastWwanLevel, /* isWifi= */false),
-                    getCallStrengthDescription(mLastWwanLevel, /* isWifi= */false));
-            notifyCallStateChange(statusIcon, mSubscriptionInfo.getSubscriptionId());
-        }
-    };
-
     // TODO: Reduce number of vars passed in, if we have the NetworkController, probably don't
     // need listener lists anymore.
     public MobileSignalController(
@@ -192,7 +125,7 @@
             SubscriptionDefaults defaults,
             Looper receiverLooper,
             CarrierConfigTracker carrierConfigTracker,
-            FeatureFlags featureFlags
+            MobileStatusTrackerFactory mobileStatusTrackerFactory
     ) {
         super("MobileSignalController(" + info.getSubscriptionId() + ")", context,
                 NetworkCapabilities.TRANSPORT_CELLULAR, callbackHandler,
@@ -206,7 +139,6 @@
                 R.string.status_bar_network_name_separator).toString();
         mNetworkNameDefault = getTextIfExists(
                 com.android.internal.R.string.lockscreen_carrier_default).toString();
-        mReceiverHandler = new Handler(receiverLooper);
 
         mNetworkToIconLookup = mapIconSets(mConfig);
         mDefaultIcons = getDefaultIcons(mConfig);
@@ -223,10 +155,7 @@
                 updateTelephony();
             }
         };
-        mImsMmTelManager = ImsMmTelManager.createForSubscriptionId(info.getSubscriptionId());
-        mMobileStatusTracker = new MobileStatusTracker(mPhone, receiverLooper,
-                info, mDefaults, mMobileCallback);
-        mProviderModelBehavior = featureFlags.isEnabled(Flags.COMBINED_STATUS_BAR_SIGNAL_ICONS);
+        mMobileStatusTracker = mobileStatusTrackerFactory.createTracker(mMobileCallback);
     }
 
     void setConfiguration(Config config) {
@@ -271,41 +200,14 @@
         mContext.getContentResolver().registerContentObserver(Global.getUriFor(
                 Global.MOBILE_DATA + mSubscriptionInfo.getSubscriptionId()),
                 true, mObserver);
-        if (mProviderModelBehavior) {
-            mReceiverHandler.post(mTryRegisterIms);
-        }
     }
 
-    // There is no listener to monitor whether the IMS service is ready, so we have to retry the
-    // IMS registration.
-    private final Runnable mTryRegisterIms = new Runnable() {
-        private static final int MAX_RETRY = 12;
-        private int mRetryCount;
-
-        @Override
-        public void run() {
-            try {
-                mRetryCount++;
-                mImsMmTelManager.registerImsRegistrationCallback(
-                        mReceiverHandler::post, mRegistrationCallback);
-                Log.d(mTag, "registerImsRegistrationCallback succeeded");
-            } catch (RuntimeException | ImsException e) {
-                if (mRetryCount < MAX_RETRY) {
-                    Log.e(mTag, mRetryCount + " registerImsRegistrationCallback failed", e);
-                    // Wait for 5 seconds to retry
-                    mReceiverHandler.postDelayed(mTryRegisterIms, 5000);
-                }
-            }
-        }
-    };
-
     /**
      * Stop listening for phone state changes.
      */
     public void unregisterListener() {
         mMobileStatusTracker.setListening(false);
         mContext.getContentResolver().unregisterContentObserver(mObserver);
-        mImsMmTelManager.unregisterImsRegistrationCallback(mRegistrationCallback);
     }
 
     private void updateInflateSignalStrength() {
@@ -394,7 +296,7 @@
         CharSequence qsDescription = null;
 
         if (mCurrentState.dataSim) {
-            // If using provider model behavior, only show QS icons if the state is also default
+            // only show QS icons if the state is also default
             if (!mCurrentState.isDefault) {
                 return new QsInfo(qsTypeIcon, qsIcon, qsDescription);
             }
@@ -416,32 +318,15 @@
 
     private SbInfo getSbInfo(String contentDescription, int dataTypeIcon) {
         final boolean dataDisabled = mCurrentState.isDataDisabledOrNotDefault();
-        boolean showTriangle = false;
-        int typeIcon = 0;
-        IconState statusIcon = null;
+        IconState statusIcon = new IconState(
+                mCurrentState.enabled && !mCurrentState.airplaneMode,
+                getCurrentIconId(), contentDescription);
 
-        if (mProviderModelBehavior) {
-            boolean showDataIconStatusBar = (mCurrentState.dataConnected || dataDisabled)
-                    && (mCurrentState.dataSim && mCurrentState.isDefault);
-            typeIcon =
-                    (showDataIconStatusBar || mConfig.alwaysShowDataRatIcon) ? dataTypeIcon : 0;
-            showDataIconStatusBar |= mCurrentState.roaming;
-            statusIcon = new IconState(
-                    showDataIconStatusBar && !mCurrentState.airplaneMode,
-                    getCurrentIconId(), contentDescription);
-
-            showTriangle = showDataIconStatusBar && !mCurrentState.airplaneMode;
-        } else {
-            statusIcon = new IconState(
-                    mCurrentState.enabled && !mCurrentState.airplaneMode,
-                    getCurrentIconId(), contentDescription);
-
-            boolean showDataIconInStatusBar =
-                    (mCurrentState.dataConnected && mCurrentState.isDefault) || dataDisabled;
-            typeIcon =
-                    (showDataIconInStatusBar || mConfig.alwaysShowDataRatIcon) ? dataTypeIcon : 0;
-            showTriangle = mCurrentState.enabled && !mCurrentState.airplaneMode;
-        }
+        boolean showDataIconInStatusBar =
+                (mCurrentState.dataConnected && mCurrentState.isDefault) || dataDisabled;
+        int typeIcon =
+                (showDataIconInStatusBar || mConfig.alwaysShowDataRatIcon) ? dataTypeIcon : 0;
+        boolean showTriangle = mCurrentState.enabled && !mCurrentState.airplaneMode;
 
         return new SbInfo(showTriangle, typeIcon, statusIcon);
     }
@@ -560,144 +445,7 @@
     }
 
     private void updateMobileStatus(MobileStatus mobileStatus) {
-        int lastVoiceState = mCurrentState.getVoiceServiceState();
         mCurrentState.setFromMobileStatus(mobileStatus);
-
-        notifyMobileLevelChangeIfNecessary(mobileStatus.signalStrength);
-        if (mProviderModelBehavior) {
-            maybeNotifyCallStateChanged(lastVoiceState);
-        }
-    }
-
-    /** Call state changed is only applicable when provider model behavior is true */
-    private void maybeNotifyCallStateChanged(int lastVoiceState) {
-        int currentVoiceState = mCurrentState.getVoiceServiceState();
-        if (lastVoiceState == currentVoiceState) {
-            return;
-        }
-        // Only update the no calling Status in the below scenarios
-        // 1. The first valid voice state has been received
-        // 2. The voice state has been changed and either the last or current state is
-        //    ServiceState.STATE_IN_SERVICE
-        if (lastVoiceState == -1
-                || (lastVoiceState == ServiceState.STATE_IN_SERVICE
-                        || currentVoiceState == ServiceState.STATE_IN_SERVICE)) {
-            boolean isNoCalling = mCurrentState.isNoCalling();
-            isNoCalling &= !hideNoCalling();
-            IconState statusIcon = new IconState(isNoCalling,
-                    R.drawable.ic_qs_no_calling_sms,
-                    getTextIfExists(AccessibilityContentDescriptions.NO_CALLING).toString());
-            notifyCallStateChange(statusIcon, mSubscriptionInfo.getSubscriptionId());
-        }
-    }
-
-    void updateNoCallingState() {
-        int currentVoiceState = mCurrentState.getVoiceServiceState();
-        boolean isNoCalling = currentVoiceState != ServiceState.STATE_IN_SERVICE;
-        isNoCalling &= !hideNoCalling();
-        IconState statusIcon = new IconState(isNoCalling,
-                R.drawable.ic_qs_no_calling_sms,
-                getTextIfExists(AccessibilityContentDescriptions.NO_CALLING).toString());
-        notifyCallStateChange(statusIcon, mSubscriptionInfo.getSubscriptionId());
-    }
-
-    private boolean hideNoCalling() {
-        return mNetworkController.hasDefaultNetwork()
-                && mCarrierConfigTracker.getNoCallingConfig(mSubscriptionInfo.getSubscriptionId());
-    }
-
-    private int getCallStrengthIcon(int level, boolean isWifi) {
-        return isWifi ? TelephonyIcons.WIFI_CALL_STRENGTH_ICONS[level]
-                : TelephonyIcons.MOBILE_CALL_STRENGTH_ICONS[level];
-    }
-
-    private String getCallStrengthDescription(int level, boolean isWifi) {
-        return isWifi
-                ? getTextIfExists(AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH[level])
-                        .toString()
-                : getTextIfExists(AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[level])
-                        .toString();
-    }
-
-    void refreshCallIndicator(SignalCallback callback) {
-        boolean isNoCalling = mCurrentState.isNoCalling();
-        isNoCalling &= !hideNoCalling();
-        IconState statusIcon = new IconState(isNoCalling,
-                R.drawable.ic_qs_no_calling_sms,
-                getTextIfExists(AccessibilityContentDescriptions.NO_CALLING).toString());
-        callback.setCallIndicator(statusIcon, mSubscriptionInfo.getSubscriptionId());
-
-        switch (mImsType) {
-            case IMS_TYPE_WWAN:
-                statusIcon = new IconState(
-                        true,
-                        getCallStrengthIcon(mLastWwanLevel, /* isWifi= */false),
-                        getCallStrengthDescription(mLastWwanLevel, /* isWifi= */false));
-                break;
-            case IMS_TYPE_WLAN:
-                statusIcon = new IconState(
-                        true,
-                        getCallStrengthIcon(mLastWlanLevel, /* isWifi= */true),
-                        getCallStrengthDescription(mLastWlanLevel, /* isWifi= */true));
-                break;
-            case IMS_TYPE_WLAN_CROSS_SIM:
-                statusIcon = new IconState(
-                        true,
-                        getCallStrengthIcon(mLastWlanCrossSimLevel, /* isWifi= */false),
-                        getCallStrengthDescription(mLastWlanCrossSimLevel, /* isWifi= */false));
-        }
-        callback.setCallIndicator(statusIcon, mSubscriptionInfo.getSubscriptionId());
-    }
-
-    void notifyWifiLevelChange(int level) {
-        if (!mProviderModelBehavior) {
-            return;
-        }
-        mLastWlanLevel = level;
-        if (mImsType != IMS_TYPE_WLAN) {
-            return;
-        }
-        IconState statusIcon = new IconState(
-                true,
-                getCallStrengthIcon(level, /* isWifi= */true),
-                getCallStrengthDescription(level, /* isWifi= */true));
-        notifyCallStateChange(statusIcon, mSubscriptionInfo.getSubscriptionId());
-    }
-
-    void notifyDefaultMobileLevelChange(int level) {
-        if (!mProviderModelBehavior) {
-            return;
-        }
-        mLastWlanCrossSimLevel = level;
-        if (mImsType != IMS_TYPE_WLAN_CROSS_SIM) {
-            return;
-        }
-        IconState statusIcon = new IconState(
-                true,
-                getCallStrengthIcon(level, /* isWifi= */false),
-                getCallStrengthDescription(level, /* isWifi= */false));
-        notifyCallStateChange(statusIcon, mSubscriptionInfo.getSubscriptionId());
-    }
-
-    void notifyMobileLevelChangeIfNecessary(SignalStrength signalStrength) {
-        if (!mProviderModelBehavior) {
-            return;
-        }
-        int newLevel = getSignalLevel(signalStrength);
-        if (newLevel != mLastLevel) {
-            mLastLevel = newLevel;
-            mLastWwanLevel = newLevel;
-            if (mImsType == IMS_TYPE_WWAN) {
-                IconState statusIcon = new IconState(
-                        true,
-                        getCallStrengthIcon(newLevel, /* isWifi= */false),
-                        getCallStrengthDescription(newLevel, /* isWifi= */false));
-                notifyCallStateChange(statusIcon, mSubscriptionInfo.getSubscriptionId());
-            }
-            if (mCurrentState.dataSim) {
-                mNetworkController.notifyDefaultMobileLevelChange(newLevel);
-            }
-        }
     }
 
     int getSignalLevel(SignalStrength signalStrength) {
@@ -801,19 +549,14 @@
         mMobileStatusHistoryIndex = (mMobileStatusHistoryIndex + 1) % STATUS_HISTORY_SIZE;
     }
 
-    @VisibleForTesting
-    void setImsType(int imsType) {
-        mImsType = imsType;
-    }
-
     @Override
     public void dump(PrintWriter pw) {
         super.dump(pw);
         pw.println("  mSubscription=" + mSubscriptionInfo + ",");
-        pw.println("  mProviderModelBehavior=" + mProviderModelBehavior + ",");
         pw.println("  mInflateSignalStrengths=" + mInflateSignalStrengths + ",");
         pw.println("  isDataDisabled=" + isDataDisabled() + ",");
         pw.println("  mNetworkToIconLookup=" + mNetworkToIconLookup + ",");
+        pw.println("  mMobileStatusTracker.isListening=" + mMobileStatusTracker.isListening());
         pw.println("  MobileStatusHistory");
         int size = 0;
         for (int i = 0; i < STATUS_HISTORY_SIZE; i++) {
@@ -843,6 +586,11 @@
             icon = iconState;
             description = desc;
         }
+
+        @Override
+        public String toString() {
+            return "QsInfo: ratTypeIcon=" + ratTypeIcon + " icon=" + icon;
+        }
     }
 
     /** Box for status bar icon info */
@@ -856,5 +604,11 @@
             ratTypeIcon = typeIcon;
             icon = iconState;
         }
+
+        @Override
+        public String toString() {
+            return "SbInfo: showTriangle=" + showTriangle + " ratTypeIcon=" + ratTypeIcon
+                    + " icon=" + icon;
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalControllerFactory.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalControllerFactory.kt
new file mode 100644
index 0000000..f0e52f1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalControllerFactory.kt
@@ -0,0 +1,64 @@
+/*
+ * 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.connectivity
+
+import android.content.Context
+import android.os.Looper
+import android.telephony.SubscriptionInfo
+import android.telephony.TelephonyManager
+import com.android.settingslib.mobile.MobileMappings
+import com.android.settingslib.mobile.MobileStatusTracker
+import com.android.systemui.util.CarrierConfigTracker
+import javax.inject.Inject
+
+/**
+ * Factory to make MobileSignalController injectable
+ */
+internal class MobileSignalControllerFactory @Inject constructor(
+    val context: Context,
+    val callbackHandler: CallbackHandler,
+    val carrierConfigTracker: CarrierConfigTracker,
+) {
+    fun createMobileSignalController(
+        config: MobileMappings.Config,
+        hasMobileData: Boolean,
+        phone: TelephonyManager,
+        networkController: NetworkControllerImpl,
+        subscriptionInfo: SubscriptionInfo,
+        subscriptionDefaults: MobileStatusTracker.SubscriptionDefaults,
+        receiverLooper: Looper,
+    ): MobileSignalController {
+        val mobileTrackerFactory = MobileStatusTrackerFactory(
+            phone,
+            receiverLooper,
+            subscriptionInfo,
+            subscriptionDefaults)
+
+        return MobileSignalController(
+            context,
+            config,
+            hasMobileData,
+            phone,
+            callbackHandler,
+            networkController,
+            subscriptionInfo,
+            subscriptionDefaults,
+            receiverLooper,
+            carrierConfigTracker,
+            mobileTrackerFactory,
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileStatusTrackerFactory.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileStatusTrackerFactory.kt
new file mode 100644
index 0000000..a4c1a198
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileStatusTrackerFactory.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.statusbar.connectivity
+
+import android.os.Looper
+import android.telephony.SubscriptionInfo
+import android.telephony.TelephonyManager
+import com.android.settingslib.mobile.MobileStatusTracker
+
+/**
+ * Factory for [MobileStatusTracker], which lives in SettingsLib
+ */
+class MobileStatusTrackerFactory (
+    val phone: TelephonyManager,
+    val receiverLooper: Looper,
+    val info: SubscriptionInfo,
+    val defaults: MobileStatusTracker.SubscriptionDefaults,
+) {
+    fun createTracker(
+        callback: MobileStatusTracker.Callback
+    ): MobileStatusTracker {
+        return MobileStatusTracker(
+            phone,
+            receiverLooper,
+            info,
+            defaults,
+            callback)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
index 268531d..ea7ec4f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
@@ -71,8 +71,6 @@
 import com.android.systemui.demomode.DemoMode;
 import com.android.systemui.demomode.DemoModeController;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.log.LogBuffer;
 import com.android.systemui.log.LogLevel;
 import com.android.systemui.log.dagger.StatusBarNetworkControllerLog;
@@ -133,12 +131,11 @@
     private final BroadcastDispatcher mBroadcastDispatcher;
     private final DemoModeController mDemoModeController;
     private final Object mLock = new Object();
-    private final boolean mProviderModelBehavior;
     private Config mConfig;
     private final CarrierConfigTracker mCarrierConfigTracker;
-    private final FeatureFlags mFeatureFlags;
     private final DumpManager mDumpManager;
     private final LogBuffer mLogBuffer;
+    private final MobileSignalControllerFactory mMobileFactory;
 
     private TelephonyCallback.ActiveDataSubscriptionIdListener mPhoneStateListener;
     private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -234,9 +231,9 @@
             DemoModeController demoModeController,
             CarrierConfigTracker carrierConfigTracker,
             WifiStatusTrackerFactory trackerFactory,
+            MobileSignalControllerFactory mobileFactory,
             @Main Handler handler,
             InternetDialogFactory internetDialogFactory,
-            FeatureFlags featureFlags,
             DumpManager dumpManager,
             @StatusBarNetworkControllerLog LogBuffer logBuffer) {
         this(context, connectivityManager,
@@ -256,8 +253,8 @@
                 demoModeController,
                 carrierConfigTracker,
                 trackerFactory,
+                mobileFactory,
                 handler,
-                featureFlags,
                 dumpManager,
                 logBuffer);
         mReceiverHandler.post(mRegisterListeners);
@@ -282,8 +279,8 @@
             DemoModeController demoModeController,
             CarrierConfigTracker carrierConfigTracker,
             WifiStatusTrackerFactory trackerFactory,
+            MobileSignalControllerFactory mobileFactory,
             @Main Handler handler,
-            FeatureFlags featureFlags,
             DumpManager dumpManager,
             LogBuffer logBuffer
     ) {
@@ -297,6 +294,7 @@
         mCallbackHandler = callbackHandler;
         mDataSaverController = new DataSaverControllerImpl(context);
         mBroadcastDispatcher = broadcastDispatcher;
+        mMobileFactory = mobileFactory;
 
         mSubscriptionManager = subManager;
         mSubDefaults = defaultsHandler;
@@ -304,7 +302,6 @@
         mHasMobileDataFeature = telephonyManager.isDataCapable();
         mDemoModeController = demoModeController;
         mCarrierConfigTracker = carrierConfigTracker;
-        mFeatureFlags = featureFlags;
         mDumpManager = dumpManager;
         mLogBuffer = logBuffer;
 
@@ -456,7 +453,6 @@
         };
 
         mDemoModeController.addCallback(this);
-        mProviderModelBehavior = mFeatureFlags.isEnabled(Flags.COMBINED_STATUS_BAR_SIGNAL_ICONS);
 
         mDumpManager.registerDumpable(TAG, this);
     }
@@ -497,16 +493,16 @@
 
         // broadcasts
         IntentFilter filter = new IntentFilter();
-        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-        filter.addAction(Intent.ACTION_SIM_STATE_CHANGED);
-        filter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
-        filter.addAction(TelephonyManager.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);
-        filter.addAction(Intent.ACTION_SERVICE_STATE);
-        filter.addAction(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED);
+        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
         filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        filter.addAction(Intent.ACTION_SERVICE_STATE);
+        filter.addAction(Intent.ACTION_SIM_STATE_CHANGED);
         filter.addAction(Settings.Panel.ACTION_INTERNET_CONNECTIVITY);
+        filter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
+        filter.addAction(TelephonyManager.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);
+        filter.addAction(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED);
+        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
         mBroadcastDispatcher.registerReceiverWithHandler(this, filter, mReceiverHandler);
         mListening = true;
 
@@ -659,20 +655,6 @@
         return controller != null ? controller.getNetworkNameForCarrierWiFi() : "";
     }
 
-    void notifyWifiLevelChange(int level) {
-        for (int i = 0; i < mMobileSignalControllers.size(); i++) {
-            MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
-            mobileSignalController.notifyWifiLevelChange(level);
-        }
-    }
-
-    void notifyDefaultMobileLevelChange(int level) {
-        for (int i = 0; i < mMobileSignalControllers.size(); i++) {
-            MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
-            mobileSignalController.notifyDefaultMobileLevelChange(level);
-        }
-    }
-
     private void notifyControllersMobileDataChanged() {
         for (int i = 0; i < mMobileSignalControllers.size(); i++) {
             MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
@@ -745,9 +727,6 @@
         for (int i = 0; i < mMobileSignalControllers.size(); i++) {
             MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
             mobileSignalController.notifyListeners(cb);
-            if (mProviderModelBehavior) {
-                mobileSignalController.refreshCallIndicator(cb);
-            }
         }
         mCallbackHandler.setListening(cb, true);
     }
@@ -862,9 +841,6 @@
         for (int i = 0; i < mMobileSignalControllers.size(); i++) {
             MobileSignalController controller = mMobileSignalControllers.valueAt(i);
             controller.setConfiguration(mConfig);
-            if (mProviderModelBehavior) {
-                controller.refreshCallIndicator(mCallbackHandler);
-            }
         }
         refreshLocale();
     }
@@ -981,11 +957,15 @@
                 mMobileSignalControllers.put(subId, cachedControllers.get(subId));
                 cachedControllers.remove(subId);
             } else {
-                MobileSignalController controller = new MobileSignalController(mContext, mConfig,
-                        mHasMobileDataFeature, mPhone.createForSubscriptionId(subId),
-                        mCallbackHandler, this, subscriptions.get(i),
-                        mSubDefaults, mReceiverHandler.getLooper(), mCarrierConfigTracker,
-                        mFeatureFlags);
+                MobileSignalController controller = mMobileFactory.createMobileSignalController(
+                        mConfig,
+                        mHasMobileDataFeature,
+                        mPhone.createForSubscriptionId(subId),
+                        this,
+                        subscriptions.get(i),
+                        mSubDefaults,
+                        mReceiverHandler.getLooper()
+                );
                 controller.setUserSetupComplete(mUserSetup);
                 mMobileSignalControllers.put(subId, controller);
                 if (subscriptions.get(i).getSimSlotIndex() == 0) {
@@ -1139,24 +1119,11 @@
                 || mValidatedTransports.get(NetworkCapabilities.TRANSPORT_ETHERNET);
 
         pushConnectivityToSignals();
-        if (mProviderModelBehavior) {
-            mNoDefaultNetwork = !mConnectedTransports.get(NetworkCapabilities.TRANSPORT_CELLULAR)
-                    && !mConnectedTransports.get(NetworkCapabilities.TRANSPORT_WIFI)
-                    && !mConnectedTransports.get(NetworkCapabilities.TRANSPORT_ETHERNET);
-            mCallbackHandler.setConnectivityStatus(mNoDefaultNetwork, !mInetCondition,
-                    mNoNetworksAvailable);
-            for (int i = 0; i < mMobileSignalControllers.size(); i++) {
-                MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
-                mobileSignalController.updateNoCallingState();
-            }
-            notifyAllListeners();
-        } else {
-            mNoDefaultNetwork = !mConnectedTransports.get(NetworkCapabilities.TRANSPORT_CELLULAR)
-                    && !mConnectedTransports.get(NetworkCapabilities.TRANSPORT_WIFI)
-                    && !mConnectedTransports.get(NetworkCapabilities.TRANSPORT_ETHERNET);
-            mCallbackHandler.setConnectivityStatus(mNoDefaultNetwork, !mInetCondition,
-                    mNoNetworksAvailable);
-        }
+        mNoDefaultNetwork = !mConnectedTransports.get(NetworkCapabilities.TRANSPORT_CELLULAR)
+                && !mConnectedTransports.get(NetworkCapabilities.TRANSPORT_WIFI)
+                && !mConnectedTransports.get(NetworkCapabilities.TRANSPORT_ETHERNET);
+        mCallbackHandler.setConnectivityStatus(mNoDefaultNetwork, !mInetCondition,
+                mNoNetworksAvailable);
     }
 
     /**
@@ -1346,7 +1313,7 @@
                 mMobileSignalControllers.clear();
                 int start = mSubscriptionManager.getActiveSubscriptionInfoCountMax();
                 for (int i = start /* get out of normal index range */; i < start + num; i++) {
-                    subs.add(addSignalController(i, i));
+                    subs.add(addDemoModeSignalController(i, i));
                 }
                 mCallbackHandler.setSubs(subs);
                 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
@@ -1372,7 +1339,7 @@
             List<SubscriptionInfo> subs = new ArrayList<>();
             while (mMobileSignalControllers.size() <= slot) {
                 int nextSlot = mMobileSignalControllers.size();
-                subs.add(addSignalController(nextSlot, nextSlot));
+                subs.add(addDemoModeSignalController(nextSlot, nextSlot));
             }
             if (!subs.isEmpty()) {
                 mCallbackHandler.setSubs(subs);
@@ -1462,14 +1429,20 @@
         mHistoryIndex = (mHistoryIndex + 1) % HISTORY_SIZE;
     }
 
-    private SubscriptionInfo addSignalController(int id, int simSlotIndex) {
+    private SubscriptionInfo addDemoModeSignalController(int id, int simSlotIndex) {
         SubscriptionInfo info = new SubscriptionInfo(id, "", simSlotIndex, "", "", 0, 0, "", 0,
                 null, null, null, "", false, null, null);
-        MobileSignalController controller = new MobileSignalController(mContext,
-                mConfig, mHasMobileDataFeature,
-                mPhone.createForSubscriptionId(info.getSubscriptionId()), mCallbackHandler, this,
-                info, mSubDefaults, mReceiverHandler.getLooper(), mCarrierConfigTracker,
-                mFeatureFlags);
+
+        MobileSignalController controller = mMobileFactory.createMobileSignalController(
+                mConfig,
+                mHasMobileDataFeature,
+                mPhone.createForSubscriptionId(info.getSubscriptionId()),
+                this,
+                info,
+                mSubDefaults,
+                mReceiverHandler.getLooper()
+        );
+
         mMobileSignalControllers.put(id, controller);
         controller.getState().userSetup = true;
         return info;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java
index 87cdb17..12f2c22 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java
@@ -222,7 +222,6 @@
         mCurrentState.connected = mWifiTracker.connected;
         mCurrentState.ssid = mWifiTracker.ssid;
         mCurrentState.rssi = mWifiTracker.rssi;
-        boolean levelChanged = mCurrentState.level != mWifiTracker.level;
         mCurrentState.level = mWifiTracker.level;
         mCurrentState.statusLabel = mWifiTracker.statusLabel;
         mCurrentState.isCarrierMerged = mWifiTracker.isCarrierMerged;
@@ -230,10 +229,6 @@
         mCurrentState.iconGroup =
                 mCurrentState.isCarrierMerged ? mCarrierMergedWifiIconGroup
                         : mUnmergedWifiIconGroup;
-
-        if (levelChanged) {
-            mNetworkController.notifyWifiLevelChange(mCurrentState.level);
-        }
     }
 
     boolean isCarrierMergedWifi(int subId) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
index a62a152..5351024 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
@@ -24,6 +24,7 @@
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment
+import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent
 import com.android.systemui.statusbar.window.StatusBarWindowController
 import java.lang.IllegalStateException
 import javax.inject.Inject
@@ -34,7 +35,8 @@
  */
 @CentralSurfacesScope
 class StatusBarInitializer @Inject constructor(
-    private val windowController: StatusBarWindowController
+    private val windowController: StatusBarWindowController,
+    private val creationListeners: Set<@JvmSuppressWildcards OnStatusBarViewInitializedListener>,
 ) {
 
     var statusBarViewUpdatedListener: OnStatusBarViewUpdatedListener? = null
@@ -56,6 +58,9 @@
                             statusBarFragmentComponent.phoneStatusBarViewController,
                             statusBarFragmentComponent.phoneStatusBarTransitions
                         )
+                        creationListeners.forEach { listener ->
+                            listener.onStatusBarViewInitialized(statusBarFragmentComponent)
+                        }
                     }
 
                     override fun onFragmentViewDestroyed(tag: String?, fragment: Fragment?) {
@@ -69,6 +74,17 @@
                 .commit()
     }
 
+    interface OnStatusBarViewInitializedListener {
+
+        /**
+         * The status bar view has been initialized.
+         *
+         * @param component Dagger component that is created when the status bar view is created.
+         * Can be used to retrieve dependencies from that scope, including the status bar root view.
+         */
+        fun onStatusBarViewInitialized(component: StatusBarFragmentComponent)
+    }
+
     interface OnStatusBarViewUpdatedListener {
         fun onStatusBarViewUpdated(
             statusBarView: PhoneStatusBarView,
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/NotifPipelineFlags.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
index c4947ca..0c6a91f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
@@ -59,4 +59,7 @@
 
     fun removeUnrankedNotifs(): Boolean =
         featureFlags.isEnabled(Flags.REMOVE_UNRANKED_NOTIFICATIONS)
+
+    fun fullScreenIntentRequiresKeyguard(): Boolean =
+        featureFlags.isEnabled(Flags.FSI_REQUIRES_KEYGUARD)
 }
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 27a7cd7..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
@@ -253,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
@@ -290,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 2dd95a3..a72b381 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
@@ -41,6 +41,7 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -58,6 +59,7 @@
 
     private final List<NotificationInterruptSuppressor> mSuppressors = new ArrayList<>();
     private final StatusBarStateController mStatusBarStateController;
+    private final KeyguardStateController mKeyguardStateController;
     private final NotificationFilter mNotificationFilter;
     private final ContentResolver mContentResolver;
     private final PowerManager mPowerManager;
@@ -82,6 +84,7 @@
             NotificationFilter notificationFilter,
             BatteryController batteryController,
             StatusBarStateController statusBarStateController,
+            KeyguardStateController keyguardStateController,
             HeadsUpManager headsUpManager,
             NotificationInterruptLogger logger,
             @Main Handler mainHandler,
@@ -94,6 +97,7 @@
         mAmbientDisplayConfiguration = ambientDisplayConfiguration;
         mNotificationFilter = notificationFilter;
         mStatusBarStateController = statusBarStateController;
+        mKeyguardStateController = keyguardStateController;
         mHeadsUpManager = headsUpManager;
         mLogger = logger;
         mFlags = flags;
@@ -177,9 +181,91 @@
      */
     @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;
+        }
+
+        // Check whether FSI requires the keyguard to be showing.
+        if (mFlags.fullScreenIntentRequiresKeyguard()) {
+
+            // If notification won't HUN and keyguard is showing, launch the FSI.
+            if (mKeyguardStateController.isShowing()) {
+                if (mKeyguardStateController.isOccluded()) {
+                    mLogger.logFullscreen(entry, "Expected not to HUN while keyguard occluded");
+                } else {
+                    // Likely LOCKED_SHADE, but launch FSI anyway
+                    mLogger.logFullscreen(entry, "Keyguard is showing and not occluded");
+                }
+                return true;
+            }
+
+            // Detect the case determined by b/231322873 to launch FSI while device is in use,
+            // as blocked by the correct implementation, and report the event.
+            final int uid = entry.getSbn().getUid();
+            android.util.EventLog.writeEvent(0x534e4554, "231322873", uid, "no hun or keyguard");
+            mLogger.logNoFullscreenWarning(entry, "Expected not to HUN while not on keyguard");
+            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 +309,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);
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..3c01802 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;
@@ -1907,6 +1909,8 @@
      * @param isEnabled whether the content views should be enabled for accessibility
      */
     private void updateContentAccessibilityImportanceForGuts(boolean isEnabled) {
+        updateAccessibilityImportance(isEnabled);
+
         if (mChildrenContainer != null) {
             updateChildAccessibilityImportance(mChildrenContainer, isEnabled);
         }
@@ -1922,6 +1926,15 @@
     }
 
     /**
+     * Updates whether this view is important for accessibility based on {@code isEnabled}.
+     */
+    private void updateAccessibilityImportance(boolean isEnabled) {
+        setImportantForAccessibility(isEnabled
+                ? View.IMPORTANT_FOR_ACCESSIBILITY_AUTO
+                : View.IMPORTANT_FOR_ACCESSIBILITY_NO);
+    }
+
+    /**
      * Updates whether the given childView is important for accessibility based on
      * {@code isEnabled}.
      */
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..defbfd8 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
@@ -343,6 +327,13 @@
     };
 
     /**
+     * Recalculate sensitiveness without animation; called when waking up while keyguard occluded.
+     */
+    public void updateSensitivenessForOccludedWakeup() {
+        mView.updateSensitiveness(false, mLockscreenUserManager.isAnyProfilePublicMode());
+    }
+
+    /**
      * Set the overexpansion of the panel to be applied to the view.
      */
     public void setOverExpansion(float overExpansion) {
@@ -636,7 +627,6 @@
             KeyguardMediaController keyguardMediaController,
             KeyguardBypassController keyguardBypassController,
             ZenModeController zenModeController,
-            SysuiColorExtractor colorExtractor,
             NotificationLockscreenUserManager lockscreenUserManager,
             MetricsLogger metricsLogger,
             DumpManager dumpManager,
@@ -649,15 +639,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 +687,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 +731,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 +1208,6 @@
         Trace.endSection();
     }
 
-    public boolean areNotificationsHiddenInShade() {
-        return mZenModeController.areNotificationsHiddenInShade();
-    }
-
     public boolean isShowingEmptyShadeView() {
         return mShowEmptyShadeView;
     }
@@ -1341,15 +1312,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 +1427,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/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index 8782be5..9070ead 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -428,7 +428,7 @@
             if (isSafetyCenterEnabled && !mAutoTracker.isAdded(mSafetySpec)) {
                 initSafetyTile();
             } else if (!isSafetyCenterEnabled && mAutoTracker.isAdded(mSafetySpec)) {
-                mHost.removeTile(CustomTile.getComponentFromSpec(mSafetySpec));
+                mHost.removeTile(mSafetySpec);
                 mHost.unmarkTileAsAutoAdded(mSafetySpec);
             }
         }
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..f4b7772 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -55,9 +55,10 @@
 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.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DisableFlagsLogger;
-import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
@@ -88,19 +89,16 @@
     private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private final AssistManager mAssistManager;
     private final DozeServiceHost mDozeServiceHost;
-    private final SysuiStatusBarStateController mStatusBarStateController;
-    private final NotificationShadeWindowView mNotificationShadeWindowView;
     private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
     private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
     private final PowerManager mPowerManager;
     private final VibratorHelper mVibratorHelper;
     private final Optional<Vibrator> mVibratorOptional;
-    private final LightBarController mLightBarController;
     private final DisableFlagsLogger mDisableFlagsLogger;
     private final int mDisplayId;
     private final boolean mVibrateOnOpening;
     private final VibrationEffect mCameraLaunchGestureVibrationEffect;
-
+    private final SystemBarAttributesListener mSystemBarAttributesListener;
 
     private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES =
             VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK);
@@ -123,16 +121,14 @@
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             AssistManager assistManager,
             DozeServiceHost dozeServiceHost,
-            SysuiStatusBarStateController statusBarStateController,
-            NotificationShadeWindowView notificationShadeWindowView,
             NotificationStackScrollLayoutController notificationStackScrollLayoutController,
             StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
             PowerManager powerManager,
             VibratorHelper vibratorHelper,
             Optional<Vibrator> vibratorOptional,
-            LightBarController lightBarController,
             DisableFlagsLogger disableFlagsLogger,
-            @DisplayId int displayId) {
+            @DisplayId int displayId,
+            SystemBarAttributesListener systemBarAttributesListener) {
 
         mCentralSurfaces = centralSurfaces;
         mContext = context;
@@ -149,20 +145,18 @@
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
         mAssistManager = assistManager;
         mDozeServiceHost = dozeServiceHost;
-        mStatusBarStateController = statusBarStateController;
-        mNotificationShadeWindowView = notificationShadeWindowView;
         mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
         mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
         mPowerManager = powerManager;
         mVibratorHelper = vibratorHelper;
         mVibratorOptional = vibratorOptional;
-        mLightBarController = lightBarController;
         mDisableFlagsLogger = disableFlagsLogger;
         mDisplayId = displayId;
 
         mVibrateOnOpening = resources.getBoolean(R.bool.config_vibrateOnIconAnimation);
         mCameraLaunchGestureVibrationEffect = getCameraGestureVibrationEffect(
                 mVibratorOptional, resources);
+        mSystemBarAttributesListener = systemBarAttributesListener;
     }
 
     @Override
@@ -188,7 +182,7 @@
     public void remQsTile(ComponentName tile) {
         QSPanelController qsPanelController = mCentralSurfaces.getQSPanelController();
         if (qsPanelController != null && qsPanelController.getHost() != null) {
-            qsPanelController.getHost().removeTile(tile);
+            qsPanelController.getHost().removeTileByUser(tile);
         }
     }
 
@@ -469,14 +463,18 @@
         if (displayId != mDisplayId) {
             return;
         }
-        boolean barModeChanged = mCentralSurfaces.setAppearance(appearance);
-
-        mLightBarController.onStatusBarAppearanceChanged(appearanceRegions, barModeChanged,
-                mCentralSurfaces.getBarMode(), navbarColorManagedByIme);
-
-        mCentralSurfaces.updateBubblesVisibility();
-        mStatusBarStateController.setSystemBarAttributes(
-                appearance, behavior, requestedVisibilities, packageName);
+        // SystemBarAttributesListener should __always__ be the top-level listener for system bar
+        // attributes changed.
+        mSystemBarAttributesListener.onSystemBarAttributesChanged(
+                displayId,
+                appearance,
+                appearanceRegions,
+                navbarColorManagedByIme,
+                behavior,
+                requestedVisibilities,
+                packageName,
+                letterboxDetails
+        );
     }
 
     @Override
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..c5aa512 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()) {
@@ -3320,11 +3308,7 @@
             return true;
         }
         if (mNotificationPanelViewController.isQsExpanded()) {
-            if (mNotificationPanelViewController.isQsDetailShowing()) {
-                mNotificationPanelViewController.closeQsDetail();
-            } else {
                 mNotificationPanelViewController.animateCloseQs(false /* animateAway */);
-            }
             return true;
         }
         if (mNotificationPanelViewController.closeUserSwitcherIfOpen()) {
@@ -3519,6 +3503,9 @@
         setBouncerShowingForStatusBarComponents(bouncerShowing);
         mStatusBarHideIconsForBouncerManager.setBouncerShowingAndTriggerUpdate(bouncerShowing);
         mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
+        if (mBouncerShowing) {
+            wakeUpIfDozing(SystemClock.uptimeMillis(), null, "BOUNCER_VISIBLE");
+        }
         updateScrimController();
         if (!mBouncerShowing) {
             updatePanelExpansionForKeyguard();
@@ -3657,6 +3644,18 @@
         public void onFinishedWakingUp() {
             mWakeUpCoordinator.setFullyAwake(true);
             mWakeUpCoordinator.setWakingUp(false);
+            if (mKeyguardStateController.isOccluded()
+                    && !mDozeParameters.canControlUnlockedScreenOff()) {
+                // When the keyguard is occluded we don't use the KEYGUARD state which would
+                // normally cause these redaction updates.  If AOD is on, the KEYGUARD state is used
+                // to show the doze, AND UnlockedScreenOffAnimationController.onFinishedWakingUp()
+                // would force a KEYGUARD state that would take care of recalculating redaction.
+                // So if AOD is off or unsupported we need to trigger these updates at screen on
+                // when the keyguard is occluded.
+                mLockscreenUserManager.updatePublicMode();
+                mNotificationPanelViewController.getNotificationStackScrollLayoutController()
+                        .updateSensitivenessForOccludedWakeup();
+            }
             if (mLaunchCameraWhenFinishedWaking) {
                 mNotificationPanelViewController.launchCamera(mLastCameraLaunchSource);
                 mLaunchCameraWhenFinishedWaking = false;
@@ -4091,8 +4090,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 +4338,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 a8913bf..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.
@@ -347,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
@@ -418,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);
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/LargeScreenShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderController.kt
deleted file mode 100644
index 84c8700..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderController.kt
+++ /dev/null
@@ -1,311 +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.app.StatusBarManager
-import android.content.res.Configuration
-import android.view.View
-import android.widget.TextView
-import androidx.constraintlayout.motion.widget.MotionLayout
-import com.android.settingslib.Utils
-import com.android.systemui.Dumpable
-import com.android.systemui.FontSizeUtils
-import com.android.systemui.R
-import com.android.systemui.animation.ShadeInterpolation
-import com.android.systemui.battery.BatteryMeterView
-import com.android.systemui.battery.BatteryMeterViewController
-import com.android.systemui.dump.DumpManager
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
-import com.android.systemui.qs.ChipVisibilityListener
-import com.android.systemui.qs.HeaderPrivacyIconsController
-import com.android.systemui.qs.carrier.QSCarrierGroup
-import com.android.systemui.qs.carrier.QSCarrierGroupController
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
-import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.LARGE_SCREEN_BATTERY_CONTROLLER
-import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.LARGE_SCREEN_SHADE_HEADER
-import com.android.systemui.statusbar.policy.ConfigurationController
-import java.io.PrintWriter
-import javax.inject.Inject
-import javax.inject.Named
-
-@CentralSurfacesScope
-class LargeScreenShadeHeaderController @Inject constructor(
-    @Named(LARGE_SCREEN_SHADE_HEADER) private val header: View,
-    private val statusBarIconController: StatusBarIconController,
-    private val privacyIconsController: HeaderPrivacyIconsController,
-    private val configurationController: ConfigurationController,
-    qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder,
-    featureFlags: FeatureFlags,
-    @Named(LARGE_SCREEN_BATTERY_CONTROLLER) batteryMeterViewController: BatteryMeterViewController,
-    dumpManager: DumpManager
-) : Dumpable {
-
-    companion object {
-        private val HEADER_TRANSITION_ID = R.id.header_transition
-        private val LARGE_SCREEN_HEADER_TRANSITION_ID = R.id.large_screen_header_transition
-        private val QQS_HEADER_CONSTRAINT = R.id.qqs_header_constraint
-        private val QS_HEADER_CONSTRAINT = R.id.qs_header_constraint
-        private val LARGE_SCREEN_HEADER_CONSTRAINT = R.id.large_screen_header_constraint
-
-        private fun Int.stateToString() = when (this) {
-            QQS_HEADER_CONSTRAINT -> "QQS Header"
-            QS_HEADER_CONSTRAINT -> "QS Header"
-            LARGE_SCREEN_HEADER_CONSTRAINT -> "Large Screen Header"
-            else -> "Unknown state"
-        }
-    }
-
-    private val combinedHeaders = featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)
-    private val iconManager: StatusBarIconController.TintedIconManager
-    private val iconContainer: StatusIconContainer
-    private val carrierIconSlots: List<String>
-    private val qsCarrierGroupController: QSCarrierGroupController
-    private val clock: TextView = header.findViewById(R.id.clock)
-    private val date: TextView = header.findViewById(R.id.date)
-    private val qsCarrierGroup: QSCarrierGroup = header.findViewById(R.id.carrier_group)
-
-    private var qsDisabled = false
-
-    private var visible = false
-        set(value) {
-            if (field == value) {
-                return
-            }
-            field = value
-            updateListeners()
-        }
-
-    var shadeExpanded = false
-        set(value) {
-            if (field == value) {
-                return
-            }
-            field = value
-            onShadeExpandedChanged()
-        }
-
-    var active = false
-        set(value) {
-            if (field == value) {
-                return
-            }
-            field = value
-            onHeaderStateChanged()
-        }
-
-    var shadeExpandedFraction = -1f
-        set(value) {
-            if (visible && field != value) {
-                header.alpha = ShadeInterpolation.getContentAlpha(value)
-                field = value
-            }
-        }
-
-    var qsExpandedFraction = -1f
-        set(value) {
-            if (visible && field != value) {
-                field = value
-                updateVisibility()
-                updatePosition()
-            }
-        }
-
-    var qsScrollY = 0
-        set(value) {
-            if (field != value) {
-                field = value
-                updateScrollY()
-            }
-        }
-
-    private val chipVisibilityListener: ChipVisibilityListener = object : ChipVisibilityListener {
-        override fun onChipVisibilityRefreshed(visible: Boolean) {
-            if (header is MotionLayout) {
-                val state = header.getConstraintSet(QQS_HEADER_CONSTRAINT).apply {
-                    setAlpha(R.id.statusIcons, if (visible) 0f else 1f)
-                    setAlpha(R.id.batteryRemainingIcon, if (visible) 0f else 1f)
-                }
-                header.updateState(QQS_HEADER_CONSTRAINT, state)
-            }
-        }
-    }
-
-    init {
-        if (header is MotionLayout) {
-            val context = header.context
-            val resources = header.resources
-            header.getConstraintSet(QQS_HEADER_CONSTRAINT)
-                    .load(context, resources.getXml(R.xml.qqs_header))
-            header.getConstraintSet(QS_HEADER_CONSTRAINT)
-                    .load(context, resources.getXml(R.xml.qs_header))
-            header.getConstraintSet(LARGE_SCREEN_HEADER_CONSTRAINT)
-                    .load(context, resources.getXml(R.xml.large_screen_shade_header))
-            privacyIconsController.chipVisibilityListener = chipVisibilityListener
-        }
-
-        bindConfigurationListener()
-
-        batteryMeterViewController.init()
-        val batteryIcon: BatteryMeterView = header.findViewById(R.id.batteryRemainingIcon)
-
-        // battery settings same as in QS icons
-        batteryMeterViewController.ignoreTunerUpdates()
-        batteryIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE)
-
-        iconContainer = header.findViewById(R.id.statusIcons)
-        iconManager = StatusBarIconController.TintedIconManager(iconContainer, featureFlags)
-        iconManager.setTint(Utils.getColorAttrDefaultColor(header.context,
-                android.R.attr.textColorPrimary))
-
-        carrierIconSlots = if (featureFlags.isEnabled(Flags.COMBINED_STATUS_BAR_SIGNAL_ICONS)) {
-            listOf(
-                header.context.getString(com.android.internal.R.string.status_bar_no_calling),
-                header.context.getString(com.android.internal.R.string.status_bar_call_strength)
-            )
-        } else {
-            listOf(header.context.getString(com.android.internal.R.string.status_bar_mobile))
-        }
-        qsCarrierGroupController = qsCarrierGroupControllerBuilder
-                .setQSCarrierGroup(header.findViewById(R.id.carrier_group))
-                .build()
-
-        dumpManager.registerDumpable(this)
-
-        updateVisibility()
-        updateConstraints()
-    }
-
-    fun disable(state1: Int, state2: Int, animate: Boolean) {
-        val disabled = state2 and StatusBarManager.DISABLE2_QUICK_SETTINGS != 0
-        if (disabled == qsDisabled) return
-        qsDisabled = disabled
-        updateVisibility()
-    }
-
-    private fun updateScrollY() {
-        if (!active && combinedHeaders) {
-            header.scrollY = qsScrollY
-        }
-    }
-
-    private fun bindConfigurationListener() {
-        val listener = object : ConfigurationController.ConfigurationListener {
-            override fun onConfigChanged(newConfig: Configuration?) {
-                val left = header.resources.getDimensionPixelSize(
-                    R.dimen.large_screen_shade_header_left_padding)
-                header.setPadding(
-                    left, header.paddingTop, header.paddingRight, header.paddingBottom)
-            }
-            override fun onDensityOrFontScaleChanged() {
-                val qsStatusStyle = R.style.TextAppearance_QS_Status
-                FontSizeUtils.updateFontSizeFromStyle(clock, qsStatusStyle)
-                FontSizeUtils.updateFontSizeFromStyle(date, qsStatusStyle)
-                qsCarrierGroup.updateTextAppearance(qsStatusStyle)
-            }
-        }
-        configurationController.addCallback(listener)
-    }
-
-    private fun onShadeExpandedChanged() {
-        if (shadeExpanded) {
-            privacyIconsController.startListening()
-        } else {
-            privacyIconsController.stopListening()
-        }
-        updateVisibility()
-        updatePosition()
-    }
-
-    private fun onHeaderStateChanged() {
-        if (active || combinedHeaders) {
-            privacyIconsController.onParentVisible()
-        } else {
-            privacyIconsController.onParentInvisible()
-        }
-        updateVisibility()
-        updateConstraints()
-    }
-
-    private fun updateVisibility() {
-        val visibility = if (!active && !combinedHeaders || qsDisabled) {
-            View.GONE
-        } else if (shadeExpanded) {
-            View.VISIBLE
-        } else {
-            View.INVISIBLE
-        }
-        if (header.visibility != visibility) {
-            header.visibility = visibility
-            visible = visibility == View.VISIBLE
-        }
-    }
-
-    private fun updateConstraints() {
-        if (!combinedHeaders) {
-            return
-        }
-        header as MotionLayout
-        if (active) {
-            header.setTransition(LARGE_SCREEN_HEADER_TRANSITION_ID)
-        } else {
-            header.setTransition(HEADER_TRANSITION_ID)
-            header.transitionToStart()
-            updatePosition()
-            updateScrollY()
-        }
-    }
-
-    private fun updatePosition() {
-        if (header is MotionLayout && !active && visible) {
-            header.setProgress(qsExpandedFraction)
-        }
-    }
-
-    private fun updateListeners() {
-        qsCarrierGroupController.setListening(visible)
-        if (visible) {
-            updateSingleCarrier(qsCarrierGroupController.isSingleCarrier)
-            qsCarrierGroupController.setOnSingleCarrierChangedListener { updateSingleCarrier(it) }
-            statusBarIconController.addIconGroup(iconManager)
-        } else {
-            qsCarrierGroupController.setOnSingleCarrierChangedListener(null)
-            statusBarIconController.removeIconGroup(iconManager)
-        }
-    }
-
-    private fun updateSingleCarrier(singleCarrier: Boolean) {
-        if (singleCarrier) {
-            iconContainer.removeIgnoredSlots(carrierIconSlots)
-        } else {
-            iconContainer.addIgnoredSlots(carrierIconSlots)
-        }
-    }
-
-    override fun dump(pw: PrintWriter, args: Array<out String>) {
-        pw.println("visible: $visible")
-        pw.println("shadeExpanded: $shadeExpanded")
-        pw.println("shadeExpandedFraction: $shadeExpandedFraction")
-        pw.println("active: $active")
-        pw.println("qsExpandedFraction: $qsExpandedFraction")
-        pw.println("qsScrollY: $qsScrollY")
-        if (combinedHeaders) {
-            header as MotionLayout
-            pw.println("currentState: ${header.currentState.stateToString()}")
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt
new file mode 100644
index 0000000..70ec13b14
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt
@@ -0,0 +1,227 @@
+/*
+ * 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 android.annotation.ColorInt
+import android.graphics.Color
+import android.graphics.Rect
+import android.view.InsetsFlags
+import android.view.ViewDebug
+import android.view.WindowInsetsController
+import android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS
+import android.view.WindowInsetsController.Appearance
+import com.android.internal.statusbar.LetterboxDetails
+import com.android.internal.util.ContrastColorUtil
+import com.android.internal.view.AppearanceRegion
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.core.StatusBarInitializer.OnStatusBarViewInitializedListener
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
+import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent
+import java.io.PrintWriter
+import java.util.Arrays
+import javax.inject.Inject
+
+class LetterboxAppearance(
+    @Appearance val appearance: Int,
+    val appearanceRegions: Array<AppearanceRegion>
+)
+
+/**
+ * Responsible for calculating the [Appearance] and [AppearanceRegion] for the status bar when apps
+ * are letterboxed.
+ */
+@CentralSurfacesScope
+class LetterboxAppearanceCalculator
+@Inject
+constructor(
+    private val lightBarController: LightBarController,
+    private val dumpManager: DumpManager,
+) : OnStatusBarViewInitializedListener, CentralSurfacesComponent.Startable {
+
+    private var statusBarBoundsProvider: StatusBarBoundsProvider? = null
+
+    override fun start() {
+        dumpManager.registerDumpable(javaClass.simpleName) { printWriter, _ -> dump(printWriter) }
+    }
+
+    override fun stop() {
+        dumpManager.unregisterDumpable(javaClass.simpleName)
+    }
+
+    private var lastAppearance: Int? = null
+    private var lastAppearanceRegions: Array<AppearanceRegion>? = null
+    private var lastLetterboxes: Array<LetterboxDetails>? = null
+    private var lastLetterboxAppearance: LetterboxAppearance? = null
+
+    fun getLetterboxAppearance(
+        @Appearance originalAppearance: Int,
+        originalAppearanceRegions: Array<AppearanceRegion>,
+        letterboxes: Array<LetterboxDetails>
+    ): LetterboxAppearance {
+        lastAppearance = originalAppearance
+        lastAppearanceRegions = originalAppearanceRegions
+        lastLetterboxes = letterboxes
+        return getLetterboxAppearanceInternal(
+                letterboxes, originalAppearance, originalAppearanceRegions)
+            .also { lastLetterboxAppearance = it }
+    }
+
+    private fun getLetterboxAppearanceInternal(
+        letterboxes: Array<LetterboxDetails>,
+        originalAppearance: Int,
+        originalAppearanceRegions: Array<AppearanceRegion>
+    ): LetterboxAppearance {
+        if (isScrimNeeded(letterboxes)) {
+            return originalAppearanceWithScrim(originalAppearance, originalAppearanceRegions)
+        }
+        val appearance = appearanceWithoutScrim(originalAppearance)
+        val appearanceRegions = getAppearanceRegions(originalAppearanceRegions, letterboxes)
+        return LetterboxAppearance(appearance, appearanceRegions.toTypedArray())
+    }
+
+    private fun isScrimNeeded(letterboxes: Array<LetterboxDetails>): Boolean {
+        if (isOuterLetterboxMultiColored()) {
+            return true
+        }
+        return letterboxes.any { letterbox ->
+            letterbox.letterboxInnerBounds.overlapsWith(getStartSideIconBounds()) ||
+                letterbox.letterboxInnerBounds.overlapsWith(getEndSideIconsBounds())
+        }
+    }
+
+    private fun getAppearanceRegions(
+        originalAppearanceRegions: Array<AppearanceRegion>,
+        letterboxes: Array<LetterboxDetails>
+    ): List<AppearanceRegion> {
+        return sanitizeAppearanceRegions(originalAppearanceRegions, letterboxes) +
+            getAllOuterAppearanceRegions(letterboxes)
+    }
+
+    private fun sanitizeAppearanceRegions(
+        originalAppearanceRegions: Array<AppearanceRegion>,
+        letterboxes: Array<LetterboxDetails>
+    ): List<AppearanceRegion> =
+        originalAppearanceRegions.map { appearanceRegion ->
+            val matchingLetterbox =
+                letterboxes.find { it.letterboxFullBounds == appearanceRegion.bounds }
+            if (matchingLetterbox == null) {
+                appearanceRegion
+            } else {
+                // When WindowManager sends appearance regions for an app, it sends them for the
+                // full bounds of its window.
+                // Here we want the bounds to be only for the inner bounds of the letterboxed app.
+                AppearanceRegion(
+                    appearanceRegion.appearance, matchingLetterbox.letterboxInnerBounds)
+            }
+        }
+
+    private fun originalAppearanceWithScrim(
+        @Appearance originalAppearance: Int,
+        originalAppearanceRegions: Array<AppearanceRegion>
+    ): LetterboxAppearance {
+        return LetterboxAppearance(
+            originalAppearance or APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS,
+            originalAppearanceRegions)
+    }
+
+    @Appearance
+    private fun appearanceWithoutScrim(@Appearance originalAppearance: Int): Int =
+        originalAppearance and APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS.inv()
+
+    private fun getAllOuterAppearanceRegions(
+        letterboxes: Array<LetterboxDetails>
+    ): List<AppearanceRegion> = letterboxes.map(this::getOuterAppearanceRegions).flatten()
+
+    private fun getOuterAppearanceRegions(
+        letterboxDetails: LetterboxDetails
+    ): List<AppearanceRegion> {
+        @Appearance val outerAppearance = getOuterAppearance()
+        return getVisibleOuterBounds(letterboxDetails).map { bounds ->
+            AppearanceRegion(outerAppearance, bounds)
+        }
+    }
+
+    private fun getVisibleOuterBounds(letterboxDetails: LetterboxDetails): List<Rect> {
+        val inner = letterboxDetails.letterboxInnerBounds
+        val outer = letterboxDetails.letterboxFullBounds
+        val top = Rect(outer.left, outer.top, outer.right, inner.top)
+        val left = Rect(outer.left, outer.top, inner.left, outer.bottom)
+        val right = Rect(inner.right, outer.top, outer.right, outer.bottom)
+        val bottom = Rect(outer.left, inner.bottom, outer.right, outer.bottom)
+        return listOf(left, top, right, bottom).filter { !it.isEmpty }
+    }
+
+    @Appearance
+    private fun getOuterAppearance(): Int {
+        val backgroundColor = outerLetterboxBackgroundColor()
+        val darkAppearanceContrast =
+            ContrastColorUtil.calculateContrast(
+                lightBarController.darkAppearanceIconColor, backgroundColor)
+        val lightAppearanceContrast =
+            ContrastColorUtil.calculateContrast(
+                lightBarController.lightAppearanceIconColor, backgroundColor)
+        return if (lightAppearanceContrast > darkAppearanceContrast) {
+            WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
+        } else {
+            0 // APPEARANCE_DEFAULT
+        }
+    }
+
+    @ColorInt
+    private fun outerLetterboxBackgroundColor(): Int {
+        // TODO(b/238607453): retrieve this information from WindowManager.
+        return Color.BLACK
+    }
+
+    private fun isOuterLetterboxMultiColored(): Boolean {
+        // TODO(b/238607453): retrieve this information from WindowManager.
+        return false
+    }
+
+    private fun getEndSideIconsBounds(): Rect {
+        return statusBarBoundsProvider?.visibleEndSideBounds ?: Rect()
+    }
+
+    private fun getStartSideIconBounds(): Rect {
+        return statusBarBoundsProvider?.visibleStartSideBounds ?: Rect()
+    }
+
+    override fun onStatusBarViewInitialized(component: StatusBarFragmentComponent) {
+        statusBarBoundsProvider = component.boundsProvider
+    }
+
+    private fun Rect.overlapsWith(other: Rect): Boolean {
+        if (this.contains(other) || other.contains(this)) {
+            return false
+        }
+        return this.intersect(other)
+    }
+
+    private fun dump(printWriter: PrintWriter) {
+        printWriter.println(
+            """
+           lastAppearance: ${lastAppearance?.toAppearanceString()}
+           lastAppearanceRegion: ${Arrays.toString(lastAppearanceRegions)},
+           lastLetterboxes: ${Arrays.toString(lastLetterboxes)},
+           lastLetterboxAppearance: $lastLetterboxAppearance
+       """.trimIndent())
+    }
+}
+
+private fun Int.toAppearanceString(): String =
+    ViewDebug.flagsToString(InsetsFlags::class.java, "appearance", this)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
index 2c57328..4d14542 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
@@ -23,8 +23,8 @@
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
 
+import android.annotation.ColorInt;
 import android.content.Context;
-import android.graphics.Color;
 import android.graphics.Rect;
 import android.view.InsetsFlags;
 import android.view.ViewDebug;
@@ -63,7 +63,8 @@
     private int mStatusBarMode;
     private int mNavigationBarMode;
     private int mNavigationMode;
-    private final Color mDarkModeColor;
+    private final int mDarkIconColor;
+    private final int mLightIconColor;
 
     /**
      * Whether the navigation bar should be light factoring in already how much alpha the scrim has
@@ -94,7 +95,8 @@
             BatteryController batteryController,
             NavigationModeController navModeController,
             DumpManager dumpManager) {
-        mDarkModeColor = Color.valueOf(ctx.getColor(R.color.dark_mode_icon_color_single_tone));
+        mDarkIconColor = ctx.getColor(R.color.dark_mode_icon_color_single_tone);
+        mLightIconColor = ctx.getColor(R.color.light_mode_icon_color_single_tone);
         mStatusBarIconController = (SysuiDarkIconDispatcher) darkIconDispatcher;
         mBatteryController = batteryController;
         mBatteryController.addCallback(this);
@@ -107,6 +109,16 @@
         }
     }
 
+    @ColorInt
+    int getLightAppearanceIconColor() {
+        return mDarkIconColor;
+    }
+
+    @ColorInt
+    int getDarkAppearanceIconColor() {
+        return mLightIconColor;
+    }
+
     public void setNavigationBar(LightBarTransitionsController navigationBar) {
         mNavigationBarController = navigationBar;
         updateNavigation();
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/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/StatusBarBoundsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarBoundsProvider.kt
new file mode 100644
index 0000000..f5ba399
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarBoundsProvider.kt
@@ -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.systemui.statusbar.phone
+
+import android.graphics.Rect
+import android.view.View
+import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent
+import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentModule.END_SIDE_CONTENT
+import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentModule.START_SIDE_CONTENT
+import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentScope
+import com.android.systemui.util.boundsOnScreen
+import javax.inject.Inject
+import javax.inject.Named
+
+/** Provides various bounds within the status bar. */
+@StatusBarFragmentScope
+class StatusBarBoundsProvider
+@Inject
+constructor(
+    private val changeListeners: Set<@JvmSuppressWildcards BoundsChangeListener>,
+    @Named(START_SIDE_CONTENT) private val startSideContent: View,
+    @Named(END_SIDE_CONTENT) private val endSideContent: View,
+) : StatusBarFragmentComponent.Startable {
+
+    interface BoundsChangeListener {
+        fun onStatusBarBoundsChanged()
+    }
+
+    private var previousBounds =
+        BoundsPair(start = startSideContent.boundsOnScreen, end = endSideContent.boundsOnScreen)
+
+    private val layoutListener =
+        View.OnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
+            val newBounds = BoundsPair(start = visibleStartSideBounds, end = visibleEndSideBounds)
+            if (previousBounds != newBounds) {
+                previousBounds = newBounds
+                changeListeners.forEach { it.onStatusBarBoundsChanged() }
+            }
+        }
+
+    override fun start() {
+        startSideContent.addOnLayoutChangeListener(layoutListener)
+        endSideContent.addOnLayoutChangeListener(layoutListener)
+    }
+
+    override fun stop() {
+        startSideContent.removeOnLayoutChangeListener(layoutListener)
+        endSideContent.removeOnLayoutChangeListener(layoutListener)
+    }
+
+    /**
+     * Returns the bounds of the end side of the status bar that are visible to the user. The end
+     * side is right when in LTR and is left when in RTL.
+     *
+     * Note that even though the layout might be larger, here we only return the bounds for what is
+     * visible to the user.
+     *
+     * The end side of the status bar contains the multi-user switcher and status icons such as
+     * wi-fi, battery, etc
+     */
+    val visibleEndSideBounds: Rect
+        get() = endSideContent.boundsOnScreen
+
+    /**
+     * Returns the bounds of the start side of the status bar that are visible to the user. The
+     * start side is left when in LTR and is right when in RTL.
+     *
+     * Note that even though the layout might be larger, here we only return the bounds for what is
+     * visible to the user.
+     *
+     * The start side of the status bar contains the operator name, clock, on-going call chip, and
+     * notifications.
+     */
+    val visibleStartSideBounds: Rect
+        get() = startSideContent.boundsOnScreen
+}
+
+private data class BoundsPair(val start: Rect, val end: Rect)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
index f5462bc..c850d4f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
@@ -123,7 +123,7 @@
         val point = Point()
         context.display.getRealSize(point)
 
-        return topBounds.left <= 0 || topBounds.right >= point.y
+        return topBounds.left <= 0 || topBounds.right >= point.x
     }
 
     /**
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..9c1512a 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);
@@ -478,7 +390,8 @@
                 return true;
             }
 
-            if (sbn.getNotification().fullScreenIntent != null) {
+            if (sbn.getNotification().fullScreenIntent != null
+                    && !mNotifPipelineFlags.fullScreenIntentRequiresKeyguard()) {
                 // we don't allow head-up on the lockscreen (unless there's a
                 // "showWhenLocked" activity currently showing)  if
                 // the potential HUN has a fullscreen intent
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
index ee242a4..492734e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
@@ -26,8 +26,6 @@
 import com.android.settingslib.mobile.TelephonyIcons;
 import com.android.systemui.R;
 import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.statusbar.connectivity.IconState;
 import com.android.systemui.statusbar.connectivity.MobileDataIndicators;
 import com.android.systemui.statusbar.connectivity.NetworkController;
@@ -66,7 +64,6 @@
     private final Handler mHandler = Handler.getMain();
     private final CarrierConfigTracker mCarrierConfigTracker;
     private final TunerService mTunerService;
-    private final FeatureFlags mFeatureFlags;
 
     private boolean mHideAirplane;
     private boolean mHideMobile;
@@ -90,8 +87,7 @@
             CarrierConfigTracker carrierConfigTracker,
             NetworkController networkController,
             SecurityController securityController,
-            TunerService tunerService,
-            FeatureFlags featureFlags
+            TunerService tunerService
     ) {
         mContext = context;
 
@@ -100,7 +96,6 @@
         mNetworkController = networkController;
         mSecurityController = securityController;
         mTunerService = tunerService;
-        mFeatureFlags = featureFlags;
 
         mSlotAirplane = mContext.getString(com.android.internal.R.string.status_bar_airplane);
         mSlotMobile   = mContext.getString(com.android.internal.R.string.status_bar_mobile);
@@ -378,40 +373,6 @@
     }
 
     @Override
-    public void setConnectivityStatus(boolean noDefaultNetwork, boolean noValidatedNetwork,
-            boolean noNetworksAvailable) {
-        if (!mFeatureFlags.isEnabled(Flags.COMBINED_STATUS_BAR_SIGNAL_ICONS)) {
-            return;
-        }
-        if (DEBUG) {
-            Log.d(TAG, "setConnectivityStatus: "
-                    + "noDefaultNetwork = " + noDefaultNetwork + ","
-                    + "noValidatedNetwork = " + noValidatedNetwork + ","
-                    + "noNetworksAvailable = " + noNetworksAvailable);
-        }
-        WifiIconState newState = mWifiIconState.copy();
-        newState.noDefaultNetwork = noDefaultNetwork;
-        newState.noValidatedNetwork = noValidatedNetwork;
-        newState.noNetworksAvailable = noNetworksAvailable;
-        newState.slot = mSlotWifi;
-        newState.airplaneSpacerVisible = mIsAirplaneMode;
-        if (noDefaultNetwork && noNetworksAvailable && !mIsAirplaneMode) {
-            newState.visible = true;
-            newState.resId = R.drawable.ic_qs_no_internet_unavailable;
-        } else if (noDefaultNetwork && !noNetworksAvailable
-                && (!mIsAirplaneMode || (mIsAirplaneMode && mIsWifiEnabled))) {
-            newState.visible = true;
-            newState.resId = R.drawable.ic_qs_no_internet_available;
-        } else {
-            newState.visible = false;
-            newState.resId = 0;
-        }
-        updateWifiIconWithState(newState);
-        mWifiIconState = newState;
-    }
-
-
-    @Override
     public void setEthernetIndicators(IconState state) {
         boolean visible = state.visible && !mHideEthernet;
         int resId = state.icon;
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/SystemBarAttributesListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt
new file mode 100644
index 0000000..a0415f2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt
@@ -0,0 +1,158 @@
+/*
+ * 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 android.view.InsetsVisibilities
+import android.view.WindowInsetsController.Appearance
+import android.view.WindowInsetsController.Behavior
+import com.android.internal.statusbar.LetterboxDetails
+import com.android.internal.view.AppearanceRegion
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
+import java.io.PrintWriter
+import javax.inject.Inject
+
+/**
+ * Top-level listener of system attributes changed. This class is __always the first__ one to be
+ * notified about changes.
+ *
+ * It is responsible for modifying any attributes if necessary, and then notifying the other
+ * downstream listeners.
+ */
+@CentralSurfacesScope
+class SystemBarAttributesListener
+@Inject
+internal constructor(
+    private val centralSurfaces: CentralSurfaces,
+    private val featureFlags: FeatureFlags,
+    private val letterboxAppearanceCalculator: LetterboxAppearanceCalculator,
+    private val statusBarStateController: SysuiStatusBarStateController,
+    private val lightBarController: LightBarController,
+    private val dumpManager: DumpManager,
+) : CentralSurfacesComponent.Startable, StatusBarBoundsProvider.BoundsChangeListener {
+
+    private var lastLetterboxAppearance: LetterboxAppearance? = null
+    private var lastSystemBarAttributesParams: SystemBarAttributesParams? = null
+
+    override fun start() {
+        dumpManager.registerDumpable(javaClass.simpleName, this::dump)
+    }
+
+    override fun stop() {
+        dumpManager.unregisterDumpable(javaClass.simpleName)
+    }
+
+    override fun onStatusBarBoundsChanged() {
+        val params = lastSystemBarAttributesParams
+        if (params != null && shouldUseLetterboxAppearance(params.letterboxesArray)) {
+            onSystemBarAttributesChanged(
+                params.displayId,
+                params.appearance,
+                params.appearanceRegionsArray,
+                params.navbarColorManagedByIme,
+                params.behavior,
+                params.requestedVisibilities,
+                params.packageName,
+                params.letterboxesArray)
+        }
+    }
+
+    fun onSystemBarAttributesChanged(
+        displayId: Int,
+        @Appearance originalAppearance: Int,
+        originalAppearanceRegions: Array<AppearanceRegion>,
+        navbarColorManagedByIme: Boolean,
+        @Behavior behavior: Int,
+        requestedVisibilities: InsetsVisibilities,
+        packageName: String,
+        letterboxDetails: Array<LetterboxDetails>
+    ) {
+        lastSystemBarAttributesParams =
+            SystemBarAttributesParams(
+                displayId,
+                originalAppearance,
+                originalAppearanceRegions.toList(),
+                navbarColorManagedByIme,
+                behavior,
+                requestedVisibilities,
+                packageName,
+                letterboxDetails.toList())
+
+        val (appearance, appearanceRegions) =
+            modifyAppearanceIfNeeded(
+                originalAppearance, originalAppearanceRegions, letterboxDetails)
+
+        val barModeChanged = centralSurfaces.setAppearance(appearance)
+
+        lightBarController.onStatusBarAppearanceChanged(
+            appearanceRegions, barModeChanged, centralSurfaces.barMode, navbarColorManagedByIme)
+
+        centralSurfaces.updateBubblesVisibility()
+        statusBarStateController.setSystemBarAttributes(
+            appearance, behavior, requestedVisibilities, packageName)
+    }
+
+    private fun modifyAppearanceIfNeeded(
+        appearance: Int,
+        appearanceRegions: Array<AppearanceRegion>,
+        letterboxDetails: Array<LetterboxDetails>
+    ): Pair<Int, Array<AppearanceRegion>> =
+        if (shouldUseLetterboxAppearance(letterboxDetails)) {
+            val letterboxAppearance =
+                letterboxAppearanceCalculator.getLetterboxAppearance(
+                    appearance, appearanceRegions, letterboxDetails)
+            lastLetterboxAppearance = letterboxAppearance
+            Pair(letterboxAppearance.appearance, letterboxAppearance.appearanceRegions)
+        } else {
+            lastLetterboxAppearance = null
+            Pair(appearance, appearanceRegions)
+        }
+
+    private fun shouldUseLetterboxAppearance(letterboxDetails: Array<LetterboxDetails>) =
+        isLetterboxAppearanceFlagEnabled() && letterboxDetails.isNotEmpty()
+
+    private fun isLetterboxAppearanceFlagEnabled() =
+        featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)
+
+    private fun dump(printWriter: PrintWriter, strings: Array<String>) {
+        printWriter.println("lastSystemBarAttributesParams: $lastSystemBarAttributesParams")
+        printWriter.println("lastLetterboxAppearance: $lastLetterboxAppearance")
+        printWriter.println("letterbox appearance flag: ${isLetterboxAppearanceFlagEnabled()}")
+    }
+}
+
+/**
+ * Keeps track of the parameters passed in
+ * [SystemBarAttributesListener.onSystemBarAttributesChanged].
+ */
+private data class SystemBarAttributesParams(
+    val displayId: Int,
+    @Appearance val appearance: Int,
+    val appearanceRegions: List<AppearanceRegion>,
+    val navbarColorManagedByIme: Boolean,
+    @Behavior val behavior: Int,
+    val requestedVisibilities: InsetsVisibilities,
+    val packageName: String,
+    val letterboxes: List<LetterboxDetails>,
+) {
+    val letterboxesArray = letterboxes.toTypedArray()
+    val appearanceRegionsArray = appearanceRegions.toTypedArray()
+}
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..64b04e9 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,10 @@
 
 import com.android.keyguard.LockIconViewController;
 import com.android.systemui.biometrics.AuthRippleController;
+import com.android.systemui.shade.LargeScreenShadeHeaderController;
+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;
@@ -32,10 +36,6 @@
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutListContainerModule;
 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/CentralSurfacesStartableModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
index 21e5ad5..d57e6a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
@@ -16,13 +16,28 @@
 
 package com.android.systemui.statusbar.phone.dagger;
 
+import com.android.systemui.statusbar.phone.LetterboxAppearanceCalculator;
+import com.android.systemui.statusbar.phone.SystemBarAttributesListener;
+
 import java.util.Set;
 
+import dagger.Binds;
 import dagger.Module;
+import dagger.multibindings.IntoSet;
 import dagger.multibindings.Multibinds;
 
 @Module
 interface CentralSurfacesStartableModule {
     @Multibinds
     Set<CentralSurfacesComponent.Startable> multibindStartables();
+
+    @Binds
+    @IntoSet
+    CentralSurfacesComponent.Startable letterboxAppearanceCalculator(
+            LetterboxAppearanceCalculator letterboxAppearanceCalculator);
+
+    @Binds
+    @IntoSet
+    CentralSurfacesComponent.Startable sysBarAttrsListener(
+            SystemBarAttributesListener systemBarAttributesListener);
 }
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..200f45f 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
@@ -30,27 +30,34 @@
 import com.android.systemui.biometrics.AuthRippleView;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.privacy.OngoingPrivacyChip;
+import com.android.systemui.shade.CombinedShadeHeadersConstraintManager;
+import com.android.systemui.shade.CombinedShadeHeadersConstraintManagerImpl;
+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;
 import com.android.systemui.statusbar.OperatorNameViewController;
+import com.android.systemui.statusbar.core.StatusBarInitializer.OnStatusBarViewInitializedListener;
 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
 import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
+import com.android.systemui.statusbar.phone.LetterboxAppearanceCalculator;
 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.StatusBarBoundsProvider;
 import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
 import com.android.systemui.statusbar.phone.StatusIconContainer;
+import com.android.systemui.statusbar.phone.SystemBarAttributesListener;
 import com.android.systemui.statusbar.phone.TapAgainView;
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentLogger;
@@ -68,8 +75,10 @@
 
 import javax.inject.Named;
 
+import dagger.Binds;
 import dagger.Module;
 import dagger.Provides;
+import dagger.multibindings.IntoSet;
 
 @Module(subcomponents = StatusBarFragmentComponent.class)
 public abstract class StatusBarViewModule {
@@ -177,6 +186,14 @@
     /** */
     @Provides
     @CentralSurfacesComponent.CentralSurfacesScope
+    public static CombinedShadeHeadersConstraintManager
+            provideCombinedShadeHeadersConstraintManager() {
+        return CombinedShadeHeadersConstraintManagerImpl.INSTANCE;
+    }
+
+    /** */
+    @Provides
+    @CentralSurfacesComponent.CentralSurfacesScope
     public static OngoingPrivacyChip getSplitShadeOngoingPrivacyChip(
             @Named(LARGE_SCREEN_SHADE_HEADER) View header) {
         return header.findViewById(R.id.privacy_chip);
@@ -236,6 +253,17 @@
         return notificationShadeWindowView.findViewById(R.id.notification_container_parent);
     }
 
+    @Binds
+    @IntoSet
+    abstract OnStatusBarViewInitializedListener statusBarInitializedListener(
+            LetterboxAppearanceCalculator letterboxAppearanceCalculator
+    );
+
+    @Binds
+    @IntoSet
+    abstract StatusBarBoundsProvider.BoundsChangeListener sysBarAttrsListenerAsBoundsListener(
+            SystemBarAttributesListener systemBarAttributesListener);
+
     /**
      * Creates a new {@link CollapsedStatusBarFragment}.
      *
@@ -267,7 +295,8 @@
             CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger,
             OperatorNameViewController.Factory operatorNameViewControllerFactory,
             SecureSettings secureSettings,
-            @Main Executor mainExecutor
+            @Main Executor mainExecutor,
+            DumpManager dumpManager
     ) {
         return new CollapsedStatusBarFragment(statusBarFragmentComponentFactory,
                 ongoingCallController,
@@ -286,7 +315,8 @@
                 collapsedStatusBarFragmentLogger,
                 operatorNameViewControllerFactory,
                 secureSettings,
-                mainExecutor);
+                mainExecutor,
+                dumpManager);
     }
 
     /**
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..f406825 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
@@ -33,6 +33,8 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.telephony.SubscriptionManager;
+import android.util.ArrayMap;
+import android.util.IndentingPrintWriter;
 import android.util.SparseArray;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -42,11 +44,14 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import com.android.systemui.Dumpable;
 import com.android.systemui.R;
 import com.android.systemui.animation.Interpolators;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dump.DumpManager;
 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,13 +60,13 @@
 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;
 import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager;
 import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
 import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent;
+import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent.Startable;
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallListener;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
@@ -71,9 +76,12 @@
 import com.android.systemui.util.CarrierConfigTracker.DefaultDataSubscriptionChangedListener;
 import com.android.systemui.util.settings.SecureSettings;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.Executor;
 
 /**
@@ -84,7 +92,7 @@
 @SuppressLint("ValidFragment")
 public class CollapsedStatusBarFragment extends Fragment implements CommandQueue.Callbacks,
         StatusBarStateController.StateListener,
-        SystemStatusAnimationCallback {
+        SystemStatusAnimationCallback, Dumpable {
 
     public static final String TAG = "CollapsedStatusBarFragment";
     private static final String EXTRA_PANEL_STATE = "panel_state";
@@ -96,7 +104,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;
@@ -118,8 +126,10 @@
     private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
     private final SecureSettings mSecureSettings;
     private final Executor mMainExecutor;
+    private final DumpManager mDumpManager;
 
     private List<String> mBlockedIcons = new ArrayList<>();
+    private Map<Startable, Startable.State> mStartableStates = new ArrayMap<>();
 
     private final OngoingCallListener mOngoingCallListener = new OngoingCallListener() {
         @Override
@@ -171,7 +181,8 @@
             CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger,
             OperatorNameViewController.Factory operatorNameViewControllerFactory,
             SecureSettings secureSettings,
-            @Main Executor mainExecutor
+            @Main Executor mainExecutor,
+            DumpManager dumpManager
     ) {
         mStatusBarFragmentComponentFactory = statusBarFragmentComponentFactory;
         mOngoingCallController = ongoingCallController;
@@ -191,6 +202,7 @@
         mOperatorNameViewControllerFactory = operatorNameViewControllerFactory;
         mSecureSettings = secureSettings;
         mMainExecutor = mainExecutor;
+        mDumpManager = dumpManager;
     }
 
     @Override
@@ -202,8 +214,15 @@
     @Override
     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
+        mDumpManager.registerDumpable(getClass().getSimpleName(), this);
         mStatusBarFragmentComponent = mStatusBarFragmentComponentFactory.create(this);
         mStatusBarFragmentComponent.init();
+        mStartableStates.clear();
+        for (Startable startable : mStatusBarFragmentComponent.getStartables()) {
+            mStartableStates.put(startable, Startable.State.STARTING);
+            startable.start();
+            mStartableStates.put(startable, Startable.State.STARTED);
+        }
 
         mStatusBar = (PhoneStatusBarView) view;
         View contents = mStatusBar.findViewById(R.id.status_bar_contents);
@@ -217,15 +236,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);
     }
@@ -302,6 +321,13 @@
         mStatusBarIconController.removeIconGroup(mDarkIconManager);
         mCarrierConfigTracker.removeCallback(mCarrierConfigCallback);
         mCarrierConfigTracker.removeDataSubscriptionChangedListener(mDefaultDataListener);
+
+        for (Startable startable : mStatusBarFragmentComponent.getStartables()) {
+            mStartableStates.put(startable, Startable.State.STOPPING);
+            startable.stop();
+            mStartableStates.put(startable, Startable.State.STOPPED);
+        }
+        mDumpManager.unregisterDumpable(getClass().getSimpleName());
     }
 
     /** Initializes views related to the notification icon area. */
@@ -351,10 +377,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 +464,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);
         }
     }
 
@@ -621,4 +647,23 @@
                     updateStatusBarLocation(left, right);
                 }
             };
+
+    @Override
+    public void dump(PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, /* singleIndent= */"  ");
+        StatusBarFragmentComponent component = mStatusBarFragmentComponent;
+        if (component == null) {
+            pw.println("StatusBarFragmentComponent is null");
+        } else {
+            Set<Startable> startables = component.getStartables();
+            pw.println("Startables: " + startables.size());
+            pw.increaseIndent();
+            for (Startable startable : startables) {
+                Startable.State startableState = mStartableStates.getOrDefault(startable,
+                        Startable.State.NONE);
+                pw.println(startable + ", state: " + startableState);
+            }
+            pw.decreaseIndent();
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java
index 6717bc7..d9a5844 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java
@@ -23,9 +23,12 @@
 import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions;
 import com.android.systemui.statusbar.phone.PhoneStatusBarView;
 import com.android.systemui.statusbar.phone.PhoneStatusBarViewController;
+import com.android.systemui.statusbar.phone.StatusBarBoundsProvider;
 import com.android.systemui.statusbar.phone.StatusBarDemoMode;
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
 
+import java.util.Set;
+
 import dagger.BindsInstance;
 import dagger.Subcomponent;
 
@@ -41,7 +44,10 @@
  * should be included here or in {@link StatusBarFragmentModule}.
  */
 
-@Subcomponent(modules = {StatusBarFragmentModule.class})
+@Subcomponent(modules = {
+        StatusBarFragmentModule.class,
+        StatusBarStartablesModule.class
+})
 @StatusBarFragmentScope
 public interface StatusBarFragmentComponent {
     /** Simple factory. */
@@ -52,6 +58,18 @@
     }
 
     /**
+     * Performs initialization logic after {@link StatusBarFragmentComponent} has been constructed.
+     */
+    interface Startable {
+        void start();
+        void stop();
+
+        enum State {
+            NONE, STARTING, STARTED, STOPPING, STOPPED
+        }
+    }
+
+    /**
      * Initialize anything extra for the component. Must be called after the component is created.
      */
     default void init() {
@@ -92,4 +110,10 @@
     /** */
     @StatusBarFragmentScope
     PhoneStatusBarTransitions getPhoneStatusBarTransitions();
+
+    /** */
+    Set<Startable> getStartables();
+
+    /** */
+    StatusBarBoundsProvider getBoundsProvider();
 }
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..41f1f95 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,11 +21,12 @@
 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;
+import com.android.systemui.statusbar.phone.StatusBarBoundsProvider;
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
 import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer;
 import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherController;
@@ -34,12 +35,14 @@
 import com.android.systemui.statusbar.window.StatusBarWindowController;
 
 import java.util.Optional;
+import java.util.Set;
 
 import javax.inject.Named;
 
 import dagger.Binds;
 import dagger.Module;
 import dagger.Provides;
+import dagger.multibindings.Multibinds;
 
 /** Dagger module for {@link StatusBarFragmentComponent}. */
 @Module
@@ -48,6 +51,8 @@
     String LIGHTS_OUT_NOTIF_VIEW = "lights_out_notif_view";
     String OPERATOR_NAME_VIEW = "operator_name_view";
     String OPERATOR_NAME_FRAME_VIEW = "operator_name_frame_view";
+    String START_SIDE_CONTENT = "start_side_content";
+    String END_SIDE_CONTENT = "end_side_content";
 
     /** */
     @Provides
@@ -68,6 +73,22 @@
     /** */
     @Provides
     @StatusBarFragmentScope
+    @Named(START_SIDE_CONTENT)
+    static View startSideContent(@RootView PhoneStatusBarView view) {
+        return view.findViewById(R.id.status_bar_start_side_content);
+    }
+
+    /** */
+    @Provides
+    @StatusBarFragmentScope
+    @Named(END_SIDE_CONTENT)
+    static View endSideContent(@RootView PhoneStatusBarView view) {
+        return view.findViewById(R.id.status_bar_end_side_content);
+    }
+
+    /** */
+    @Provides
+    @StatusBarFragmentScope
     @Named(LIGHTS_OUT_NOTIF_VIEW)
     static View provideLightsOutNotifView(@RootView PhoneStatusBarView view) {
         return view.findViewById(R.id.notification_lights_out);
@@ -138,4 +159,8 @@
     static HeadsUpStatusBarView providesHeasdUpStatusBarView(@RootView PhoneStatusBarView view) {
         return view.findViewById(R.id.heads_up_status_bar_view);
     }
+
+    /** */
+    @Multibinds
+    Set<StatusBarBoundsProvider.BoundsChangeListener> boundsChangeListeners();
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarStartablesModule.kt
similarity index 61%
copy from packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java
copy to packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarStartablesModule.kt
index 2aaf6a5..9003d13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarStartablesModule.kt
@@ -14,17 +14,19 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.statusbar.phone.fragment.dagger
 
-import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.statusbar.phone.StatusBarBoundsProvider
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.IntoSet
 
-import dagger.Binds;
-import dagger.Module;
-
-/** Provides a {@link NotifPanelEvents} in {@link SysUISingleton} scope. */
 @Module
-public abstract class NotifPanelEventsModule {
+internal interface StatusBarStartablesModule {
+
     @Binds
-    abstract NotifPanelEvents bindPanelEvents(
-            NotificationPanelViewController.PanelEventsEmitter impl);
+    @IntoSet
+    fun statusBarBoundsCalculator(
+        statusBarBoundsProvider: StatusBarBoundsProvider
+    ): StatusBarFragmentComponent.Startable
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt
new file mode 100644
index 0000000..bd6cf9a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.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.statusbar.pipeline
+
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+/**
+ * A processor that transforms raw connectivity information that we get from callbacks and turns it
+ * into a list of displayable connectivity information.
+ *
+ * This will be used for the new status bar pipeline to calculate the list of icons that should be
+ * displayed in the RHS of the status bar.
+ */
+@SysUISingleton
+class ConnectivityInfoProcessor @Inject constructor()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
new file mode 100644
index 0000000..734bd2d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.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.statusbar.pipeline.dagger
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.pipeline.ConnectivityInfoProcessor
+import dagger.Lazy
+import dagger.Module
+import dagger.Provides
+import java.util.Optional
+
+@Module
+class StatusBarPipelineModule {
+    @Provides
+    @SysUISingleton
+    fun provideConnectivityInfoProcessor(
+            featureFlags: FeatureFlags,
+            processorLazy: Lazy<ConnectivityInfoProcessor>
+    ): Optional<ConnectivityInfoProcessor> {
+        return if (featureFlags.isEnabled(Flags.NEW_STATUS_BAR_PIPELINE)) {
+            Optional.of(processorLazy.get())
+        } else {
+            Optional.empty()
+        }
+    }
+}
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..86e7456 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() {
@@ -154,6 +155,7 @@
                 .inflate(R.layout.brightness_mirror_container, mStatusBarWindow, false);
         mToggleSliderController = setMirrorLayout();
         mStatusBarWindow.addView(mBrightnessMirror, index);
+        updateResources();
 
         for (int i = 0; i < mBrightnessMirrorListeners.size(); i++) {
             mBrightnessMirrorListeners.valueAt(i).onBrightnessMirrorReinflated(mBrightnessMirror);
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/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/ConvenienceExtensions.kt b/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt
index 57b3f53..ec7aabb 100644
--- a/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt
@@ -16,7 +16,9 @@
 
 package com.android.systemui.util
 
+import android.graphics.Rect
 import android.util.IndentingPrintWriter
+import android.view.View
 import android.view.ViewGroup
 import java.io.PrintWriter
 
@@ -45,4 +47,12 @@
     if (this is IndentingPrintWriter) increaseIndent()
     block()
     if (this is IndentingPrintWriter) decreaseIndent()
-}
\ No newline at end of file
+}
+
+/** Convenience extension property for [View.getBoundsOnScreen]. */
+val View.boundsOnScreen: Rect
+    get() {
+        val bounds = Rect()
+        getBoundsOnScreen(bounds)
+        return bounds
+    }
diff --git a/packages/SystemUI/src/com/android/systemui/util/NoRemeasureMotionLayout.kt b/packages/SystemUI/src/com/android/systemui/util/NoRemeasureMotionLayout.kt
new file mode 100644
index 0000000..3095d80
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/NoRemeasureMotionLayout.kt
@@ -0,0 +1,57 @@
+/*
+ * 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.content.Context
+import android.util.AttributeSet
+import android.view.Choreographer
+import androidx.constraintlayout.motion.widget.MotionLayout
+
+/**
+ * [MotionLayout] that avoids remeasuring with the same inputs in the same frame.
+ *
+ * This is important when this view is the child of a view that performs more than one measure pass
+ * (e.g. [LinearLayout] or [ConstraintLayout]). In those cases, if this view is measured with the
+ * same inputs in the same frame, we use the last result.
+ */
+class NoRemeasureMotionLayout @JvmOverloads constructor(
+    context: Context,
+    attrs: AttributeSet?,
+    defStyle: Int = 0
+) : MotionLayout(context, attrs, defStyle) {
+
+    private var lastWidthSpec: Int? = null
+    private var lastHeightSpec: Int? = null
+    private var lastFrame: Long? = null
+
+    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+        if (
+            lastWidthSpec == widthMeasureSpec &&
+            lastHeightSpec == heightMeasureSpec &&
+            Choreographer.getMainThreadInstance()?.frameTime == lastFrame
+        ) {
+            setMeasuredDimension(measuredWidth, measuredHeight)
+            return
+        }
+        traceSection("NoRemeasureMotionLayout - measure") {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+            lastWidthSpec = widthMeasureSpec
+            lastHeightSpec = heightMeasureSpec
+            lastFrame = Choreographer.getMainThreadInstance()?.frameTime
+        }
+    }
+}
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/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..12597e0 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;
@@ -55,10 +54,6 @@
 import com.android.systemui.statusbar.policy.UserInfoController;
 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 +62,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 +102,15 @@
                     | 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 +119,19 @@
     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 +139,49 @@
             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 +189,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 +200,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 +212,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 +257,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 +307,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
@@ -404,8 +321,7 @@
     @Override
     public void dump(PrintWriter pw, String[] args) {
         // Handle commands if provided
-        if (mShellCommandHandler.isPresent()
-                && mShellCommandHandler.get().handleCommand(args, pw)) {
+        if (mShell.handleCommand(args, pw)) {
             return;
         }
         // Handle logging commands if provided
@@ -413,8 +329,7 @@
             return;
         }
         // Dump WMShell stuff here if no commands were handled
-        mShellCommandHandler.ifPresent(
-                shellCommandHandler -> shellCommandHandler.dump(pw));
+        mShell.dump(pw);
     }
 
     @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/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/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/controls/management/AppAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt
new file mode 100644
index 0000000..1e4a9e4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt
@@ -0,0 +1,84 @@
+/*
+ * 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.controls.management
+
+import android.content.ComponentName
+import android.content.res.Resources
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.LayoutInflater
+import androidx.test.filters.SmallTest
+import com.android.settingslib.core.lifecycle.Lifecycle
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.controls.ControlsServiceInfo
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.time.FakeSystemClock
+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.Mock
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class AppAdapterTest : SysuiTestCase() {
+    private val fakeSystemClock = FakeSystemClock()
+    private val backgroundExecutor = FakeExecutor(fakeSystemClock)
+    private val uiExecutor = FakeExecutor(fakeSystemClock)
+    @Mock lateinit var lifecycle: Lifecycle
+    @Mock lateinit var controlsListingController: ControlsListingController
+    @Mock lateinit var layoutInflater: LayoutInflater
+    @Mock lateinit var onAppSelected: (ComponentName?) -> Unit
+    @Mock lateinit var favoritesRenderer: FavoritesRenderer
+    val resources: Resources = context.resources
+    lateinit var adapter: AppAdapter
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        adapter = AppAdapter(backgroundExecutor,
+            uiExecutor,
+            lifecycle,
+            controlsListingController,
+            layoutInflater,
+            onAppSelected,
+            favoritesRenderer,
+            resources)
+    }
+
+    @Test
+    fun testOnServicesUpdated_nullLoadLabel() {
+        val captor = ArgumentCaptor
+            .forClass(ControlsListingController.ControlsListingCallback::class.java)
+        val controlsServiceInfo = mock(ControlsServiceInfo::class.java)
+        val serviceInfo = listOf(controlsServiceInfo)
+        `when`(controlsServiceInfo.loadLabel()).thenReturn(null)
+        verify(controlsListingController).observe(any(Lifecycle::class.java), captor.capture())
+
+        captor.value.onServicesUpdated(serviceInfo)
+        backgroundExecutor.runAllReady()
+        uiExecutor.runAllReady()
+
+        assertThat(adapter.itemCount).isEqualTo(serviceInfo.size)
+    }
+}
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/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/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index 664af75..32c66d2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -32,8 +32,6 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.LayoutInflater;
@@ -42,36 +40,23 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.internal.logging.UiEventLogger;
 import com.android.keyguard.BouncerPanelExpansionCalculator;
 import com.android.systemui.R;
 import com.android.systemui.SysuiBaseFragmentTest;
 import com.android.systemui.animation.ShadeInterpolation;
-import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.media.MediaHost;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.qs.customize.QSCustomizerController;
 import com.android.systemui.qs.dagger.QSFragmentComponent;
-import com.android.systemui.qs.external.CustomTileStatePersister;
-import com.android.systemui.qs.external.TileLifecycleManager;
 import com.android.systemui.qs.external.TileServiceRequestController;
-import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.qs.tileimpl.QSFactoryImpl;
-import com.android.systemui.settings.UserTracker;
-import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.phone.AutoTileManager;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
-import com.android.systemui.tuner.TunerService;
 import com.android.systemui.util.animation.UniqueObjectHostView;
-import com.android.systemui.util.settings.SecureSettings;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -79,8 +64,6 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import java.util.Optional;
-
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper(setAsMainLooper = true)
 @SmallTest
@@ -125,34 +108,11 @@
         mFragments.dispatchResume();
         processAllMessages();
 
-        QSTileHost host =
-                new QSTileHost(
-                        mContext,
-                        mock(StatusBarIconController.class),
-                        mock(QSFactoryImpl.class),
-                        new Handler(),
-                        Looper.myLooper(),
-                        mock(PluginManager.class),
-                        mock(TunerService.class),
-                        () -> mock(AutoTileManager.class),
-                        mock(DumpManager.class),
-                        mock(BroadcastDispatcher.class),
-                        Optional.of(mock(CentralSurfaces.class)),
-                        mock(QSLogger.class),
-                        mock(UiEventLogger.class),
-                        mock(UserTracker.class),
-                        mock(SecureSettings.class),
-                        mock(CustomTileStatePersister.class),
-                        mTileServiceRequestControllerBuilder,
-                        mock(TileLifecycleManager.Factory.class));
-
         qs.setListening(true);
         processAllMessages();
 
         qs.setListening(false);
         processAllMessages();
-        host.destroy();
-        processAllMessages();
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
index 8cf3fe2..7dbc561 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
@@ -32,12 +32,11 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.database.ContentObserver;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.UserHandle;
 import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
 import android.view.View;
 
 import androidx.annotation.Nullable;
@@ -48,7 +47,6 @@
 import com.android.internal.util.CollectionUtils;
 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.dump.DumpManager;
 import com.android.systemui.plugins.ActivityStarter;
@@ -68,8 +66,10 @@
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.tuner.TunerService;
+import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.settings.FakeSettings;
 import com.android.systemui.util.settings.SecureSettings;
+import com.android.systemui.util.time.FakeSystemClock;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -81,18 +81,19 @@
 import java.io.StringWriter;
 import java.util.List;
 import java.util.Optional;
+import java.util.concurrent.Executor;
 
 import javax.inject.Provider;
 
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
-@RunWithLooper(setAsMainLooper = true)
 public class QSTileHostTest extends SysuiTestCase {
 
     private static String MOCK_STATE_STRING = "MockState";
     private static ComponentName CUSTOM_TILE =
             ComponentName.unflattenFromString("TEST_PKG/.TEST_CLS");
     private static final String CUSTOM_TILE_SPEC = CustomTile.toSpec(CUSTOM_TILE);
+    private static final String SETTING = QSTileHost.TILES_SETTING;
 
     @Mock
     private StatusBarIconController mIconController;
@@ -107,8 +108,6 @@
     @Mock
     private DumpManager mDumpManager;
     @Mock
-    private BroadcastDispatcher mBroadcastDispatcher;
-    @Mock
     private QSTile.State mMockState;
     @Mock
     private CentralSurfaces mCentralSurfaces;
@@ -132,31 +131,47 @@
     @Mock
     private TileLifecycleManager mTileLifecycleManager;
 
-    private Handler mHandler;
-    private TestableLooper mLooper;
+    private FakeExecutor mMainExecutor;
+
     private QSTileHost mQSTileHost;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mLooper = TestableLooper.get(this);
-        mHandler = new Handler(mLooper.getLooper());
+        mMainExecutor = new FakeExecutor(new FakeSystemClock());
+
         when(mTileServiceRequestControllerBuilder.create(any()))
                 .thenReturn(mTileServiceRequestController);
         when(mTileLifecycleManagerFactory.create(any(Intent.class), any(UserHandle.class)))
                 .thenReturn(mTileLifecycleManager);
 
         mSecureSettings = new FakeSettings();
-        mSecureSettings.putStringForUser(
-                QSTileHost.TILES_SETTING, "", "", false, mUserTracker.getUserId(), false);
-        mQSTileHost = new TestQSTileHost(mContext, mIconController, mDefaultFactory, mHandler,
-                mLooper.getLooper(), mPluginManager, mTunerService, mAutoTiles, mDumpManager,
-                mBroadcastDispatcher, mCentralSurfaces, mQSLogger, mUiEventLogger, mUserTracker,
-                mSecureSettings, mCustomTileStatePersister, mTileServiceRequestControllerBuilder,
-                mTileLifecycleManagerFactory);
+        saveSetting("");
+        mQSTileHost = new TestQSTileHost(mContext, mIconController, mDefaultFactory, mMainExecutor,
+                mPluginManager, mTunerService, mAutoTiles, mDumpManager, mCentralSurfaces,
+                mQSLogger, mUiEventLogger, mUserTracker, mSecureSettings, mCustomTileStatePersister,
+                mTileServiceRequestControllerBuilder, mTileLifecycleManagerFactory);
+
+        mSecureSettings.registerContentObserverForUser(SETTING, new ContentObserver(null) {
+            @Override
+            public void onChange(boolean selfChange) {
+                super.onChange(selfChange);
+                mMainExecutor.execute(() -> mQSTileHost.onTuningChanged(SETTING, getSetting()));
+                mMainExecutor.runAllReady();
+            }
+        }, mUserTracker.getUserId());
         setUpTileFactory();
     }
 
+    private void saveSetting(String value) {
+        mSecureSettings.putStringForUser(
+                SETTING, value, "", false, mUserTracker.getUserId(), false);
+    }
+
+    private String getSetting() {
+        return mSecureSettings.getStringForUser(SETTING, mUserTracker.getUserId());
+    }
+
     private void setUpTileFactory() {
         when(mMockState.toString()).thenReturn(MOCK_STATE_STRING);
         // Only create this kind of tiles
@@ -173,6 +188,10 @@
                         return new NotAvailableTile(mQSTileHost);
                     } else if (CUSTOM_TILE_SPEC.equals(spec)) {
                         return mCustomTile;
+                    } else if ("internet".equals(spec)
+                            || "wifi".equals(spec)
+                            || "cell".equals(spec)) {
+                        return new TestTile1(mQSTileHost);
                     } else {
                         return null;
                     }
@@ -196,14 +215,14 @@
     public void testInvalidSpecUsesDefault() {
         mContext.getOrCreateTestableResources()
                 .addOverride(R.string.quick_settings_tiles, "spec1,spec2");
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "not-valid");
+        saveSetting("not-valid");
 
         assertEquals(2, mQSTileHost.getTiles().size());
     }
 
     @Test
     public void testRemoveWifiAndCellularWithoutInternet() {
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "wifi, spec1, cell, spec2");
+        saveSetting("wifi, spec1, cell, spec2");
 
         assertEquals("internet", mQSTileHost.mTileSpecs.get(0));
         assertEquals("spec1", mQSTileHost.mTileSpecs.get(1));
@@ -212,7 +231,7 @@
 
     @Test
     public void testRemoveWifiAndCellularWithInternet() {
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "wifi, spec1, cell, spec2, internet");
+        saveSetting("wifi, spec1, cell, spec2, internet");
 
         assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
         assertEquals("spec2", mQSTileHost.mTileSpecs.get(1));
@@ -221,7 +240,7 @@
 
     @Test
     public void testRemoveWifiWithoutInternet() {
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1, wifi, spec2");
+        saveSetting("spec1, wifi, spec2");
 
         assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
         assertEquals("internet", mQSTileHost.mTileSpecs.get(1));
@@ -230,7 +249,7 @@
 
     @Test
     public void testRemoveCellWithInternet() {
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1, spec2, cell, internet");
+        saveSetting("spec1, spec2, cell, internet");
 
         assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
         assertEquals("spec2", mQSTileHost.mTileSpecs.get(1));
@@ -239,7 +258,7 @@
 
     @Test
     public void testNoWifiNoCellularNoInternet() {
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec2");
+        saveSetting("spec1,spec2");
 
         assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
         assertEquals("spec2", mQSTileHost.mTileSpecs.get(1));
@@ -249,7 +268,7 @@
     public void testSpecWithInvalidDoesNotUseDefault() {
         mContext.getOrCreateTestableResources()
                 .addOverride(R.string.quick_settings_tiles, "spec1,spec2");
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec2,not-valid");
+        saveSetting("spec2,not-valid");
 
         assertEquals(1, mQSTileHost.getTiles().size());
         QSTile element = CollectionUtils.firstOrNull(mQSTileHost.getTiles());
@@ -258,7 +277,7 @@
 
     @Test
     public void testDump() {
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec2");
+        saveSetting("spec1,spec2");
         StringWriter w = new StringWriter();
         PrintWriter pw = new PrintWriter(w);
         mQSTileHost.dump(pw, new String[]{});
@@ -274,7 +293,7 @@
     public void testDefault() {
         mContext.getOrCreateTestableResources()
                 .addOverride(R.string.quick_settings_tiles_default, "spec1");
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "default");
+        saveSetting("default");
         assertEquals(1, mQSTileHost.getTiles().size());
         QSTile element = CollectionUtils.firstOrNull(mQSTileHost.getTiles());
         assertTrue(element instanceof TestTile1);
@@ -285,7 +304,7 @@
     public void testNoRepeatedSpecs_addTile() {
         mContext.getOrCreateTestableResources()
                 .addOverride(R.string.quick_settings_tiles, "spec1,spec2");
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec2");
+        saveSetting("spec1,spec2");
 
         mQSTileHost.addTile("spec1");
 
@@ -298,9 +317,10 @@
     public void testAddTileAtValidPosition() {
         mContext.getOrCreateTestableResources()
                 .addOverride(R.string.quick_settings_tiles, "spec1,spec3");
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec3");
+        saveSetting("spec1,spec3");
 
         mQSTileHost.addTile("spec2", 1);
+        mMainExecutor.runAllReady();
 
         assertEquals(3, mQSTileHost.mTileSpecs.size());
         assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
@@ -312,9 +332,10 @@
     public void testAddTileAtInvalidPositionAddsToEnd() {
         mContext.getOrCreateTestableResources()
                 .addOverride(R.string.quick_settings_tiles, "spec1,spec3");
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec3");
+        saveSetting("spec1,spec3");
 
         mQSTileHost.addTile("spec2", 100);
+        mMainExecutor.runAllReady();
 
         assertEquals(3, mQSTileHost.mTileSpecs.size());
         assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
@@ -326,9 +347,10 @@
     public void testAddTileAtEnd() {
         mContext.getOrCreateTestableResources()
                 .addOverride(R.string.quick_settings_tiles, "spec1,spec3");
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec3");
+        saveSetting("spec1,spec3");
 
         mQSTileHost.addTile("spec2", QSTileHost.POSITION_AT_END);
+        mMainExecutor.runAllReady();
 
         assertEquals(3, mQSTileHost.mTileSpecs.size());
         assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
@@ -338,9 +360,10 @@
 
     @Test
     public void testNoRepeatedSpecs_customTile() {
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, CUSTOM_TILE_SPEC);
+        saveSetting(CUSTOM_TILE_SPEC);
 
         mQSTileHost.addTile(CUSTOM_TILE, /* end */ false);
+        mMainExecutor.runAllReady();
 
         assertEquals(1, mQSTileHost.mTileSpecs.size());
         assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.mTileSpecs.get(0));
@@ -348,9 +371,10 @@
 
     @Test
     public void testAddedAtBeginningOnDefault_customTile() {
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1"); // seed
+        saveSetting("spec1"); // seed
 
         mQSTileHost.addTile(CUSTOM_TILE);
+        mMainExecutor.runAllReady();
 
         assertEquals(2, mQSTileHost.mTileSpecs.size());
         assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.mTileSpecs.get(0));
@@ -358,9 +382,10 @@
 
     @Test
     public void testAddedAtBeginning_customTile() {
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1"); // seed
+        saveSetting("spec1"); // seed
 
         mQSTileHost.addTile(CUSTOM_TILE, /* end */ false);
+        mMainExecutor.runAllReady();
 
         assertEquals(2, mQSTileHost.mTileSpecs.size());
         assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.mTileSpecs.get(0));
@@ -368,9 +393,10 @@
 
     @Test
     public void testAddedAtEnd_customTile() {
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1"); // seed
+        saveSetting("spec1"); // seed
 
         mQSTileHost.addTile(CUSTOM_TILE, /* end */ true);
+        mMainExecutor.runAllReady();
 
         assertEquals(2, mQSTileHost.mTileSpecs.size());
         assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.mTileSpecs.get(1));
@@ -409,13 +435,13 @@
 
     @Test
     public void testNotAvailableTile_specNotNull() {
-        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "na");
+        saveSetting("na");
         verify(mQSLogger, never()).logTileDestroyed(isNull(), anyString());
     }
 
     @Test
     public void testCustomTileRemoved_stateDeleted() {
-        mQSTileHost.changeTiles(List.of(CUSTOM_TILE_SPEC), List.of());
+        mQSTileHost.changeTilesByUser(List.of(CUSTOM_TILE_SPEC), List.of());
 
         verify(mCustomTileStatePersister)
                 .removeState(new TileServiceKey(CUSTOM_TILE, mQSTileHost.getUserId()));
@@ -423,29 +449,99 @@
 
     @Test
     public void testRemoveTiles() {
-        List<String> tiles = List.of("spec1", "spec2", "spec3");
-        mQSTileHost.saveTilesToSettings(tiles);
+        saveSetting("spec1,spec2,spec3");
 
         mQSTileHost.removeTiles(List.of("spec1", "spec2"));
 
+        mMainExecutor.runAllReady();
         assertEquals(List.of("spec3"), mQSTileHost.mTileSpecs);
     }
 
+    @Test
+    public void testTilesRemovedInQuickSuccession() {
+        saveSetting("spec1,spec2,spec3");
+        mQSTileHost.removeTile("spec1");
+        mQSTileHost.removeTile("spec3");
+
+        mMainExecutor.runAllReady();
+        assertEquals(List.of("spec2"), mQSTileHost.mTileSpecs);
+        assertEquals("spec2", getSetting());
+    }
+
+    @Test
+    public void testAddTileInMainThread() {
+        saveSetting("spec1,spec2");
+
+        mQSTileHost.addTile("spec3");
+        assertEquals(List.of("spec1", "spec2"), mQSTileHost.mTileSpecs);
+
+        mMainExecutor.runAllReady();
+        assertEquals(List.of("spec1", "spec2", "spec3"), mQSTileHost.mTileSpecs);
+    }
+
+    @Test
+    public void testRemoveTileInMainThread() {
+        saveSetting("spec1,spec2");
+
+        mQSTileHost.removeTile("spec1");
+        assertEquals(List.of("spec1", "spec2"), mQSTileHost.mTileSpecs);
+
+        mMainExecutor.runAllReady();
+        assertEquals(List.of("spec2"), mQSTileHost.mTileSpecs);
+    }
+
+    @Test
+    public void testRemoveTilesInMainThread() {
+        saveSetting("spec1,spec2,spec3");
+
+        mQSTileHost.removeTiles(List.of("spec3", "spec1"));
+        assertEquals(List.of("spec1", "spec2", "spec3"), mQSTileHost.mTileSpecs);
+
+        mMainExecutor.runAllReady();
+        assertEquals(List.of("spec2"), mQSTileHost.mTileSpecs);
+    }
+
+    @Test
+    public void testRemoveTileByUserInMainThread() {
+        saveSetting("spec1," + CUSTOM_TILE_SPEC);
+
+        mQSTileHost.removeTileByUser(CUSTOM_TILE);
+        assertEquals(List.of("spec1", CUSTOM_TILE_SPEC), mQSTileHost.mTileSpecs);
+
+        mMainExecutor.runAllReady();
+        assertEquals(List.of("spec1"), mQSTileHost.mTileSpecs);
+    }
+
+    @Test
+    public void testNonValidTileNotStoredInSettings() {
+        saveSetting("spec1,not-valid");
+
+        assertEquals(List.of("spec1"), mQSTileHost.mTileSpecs);
+        assertEquals("spec1", getSetting());
+    }
+
+    @Test
+    public void testNotAvailableTileNotStoredInSettings() {
+        saveSetting("spec1,na");
+
+        assertEquals(List.of("spec1"), mQSTileHost.mTileSpecs);
+        assertEquals("spec1", getSetting());
+    }
+
     private class TestQSTileHost extends QSTileHost {
         TestQSTileHost(Context context, StatusBarIconController iconController,
-                QSFactory defaultFactory, Handler mainHandler, Looper bgLooper,
+                QSFactory defaultFactory, Executor mainExecutor,
                 PluginManager pluginManager, TunerService tunerService,
                 Provider<AutoTileManager> autoTiles, DumpManager dumpManager,
-                BroadcastDispatcher broadcastDispatcher, CentralSurfaces centralSurfaces,
-                QSLogger qsLogger, UiEventLogger uiEventLogger, UserTracker userTracker,
-                SecureSettings secureSettings, CustomTileStatePersister customTileStatePersister,
+                CentralSurfaces centralSurfaces, QSLogger qsLogger, UiEventLogger uiEventLogger,
+                UserTracker userTracker, SecureSettings secureSettings,
+                CustomTileStatePersister customTileStatePersister,
                 TileServiceRequestController.Builder tileServiceRequestControllerBuilder,
                 TileLifecycleManager.Factory tileLifecycleManagerFactory) {
-            super(context, iconController, defaultFactory, mainHandler, bgLooper, pluginManager,
-                    tunerService, autoTiles, dumpManager, broadcastDispatcher,
-                    Optional.of(centralSurfaces), qsLogger, uiEventLogger, userTracker,
-                    secureSettings, customTileStatePersister, tileServiceRequestControllerBuilder,
-                    tileLifecycleManagerFactory);
+            super(context, iconController, defaultFactory, mainExecutor, pluginManager,
+                    tunerService, autoTiles, dumpManager, Optional.of(centralSurfaces), qsLogger,
+                    uiEventLogger, userTracker, secureSettings, customTileStatePersister,
+                    tileServiceRequestControllerBuilder, tileLifecycleManagerFactory);
         }
 
         @Override
@@ -455,25 +551,16 @@
         @Override
         public void onPluginDisconnected(QSFactory plugin) {
         }
-
-        @Override
-        void saveTilesToSettings(List<String> tileSpecs) {
-            super.saveTilesToSettings(tileSpecs);
-            // After tiles are changed, make sure to call onTuningChanged with the new setting if it
-            // changed
-            String specs = mSecureSettings.getStringForUser(
-                    QSTileHost.TILES_SETTING, mUserTracker.getUserId());
-            onTuningChanged(TILES_SETTING, specs);
-        }
     }
 
+
     private class TestTile extends QSTileImpl<QSTile.State> {
 
         protected TestTile(QSHost host) {
             super(
                     host,
-                    mLooper.getLooper(),
-                    new Handler(mLooper.getLooper()),
+                    mock(Looper.class),
+                    mock(Handler.class),
                     new FalsingManagerFake(),
                     mock(MetricsLogger.class),
                     mock(StatusBarStateController.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
index 07c8af9..be14cc5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.colorextraction.SysuiColorExtractor
 import com.android.systemui.demomode.DemoModeController
 import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
 import com.android.systemui.qs.carrier.QSCarrierGroup
 import com.android.systemui.qs.carrier.QSCarrierGroupController
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
@@ -46,10 +45,10 @@
 import org.mockito.Answers
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.anyBoolean
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
 @SmallTest
@@ -162,7 +161,6 @@
 
     @Test
     fun testRSSISlot_notCombined() {
-        `when`(featureFlags.isEnabled(Flags.COMBINED_STATUS_BAR_SIGNAL_ICONS)).thenReturn(false)
         controller.init()
 
         val captor = argumentCaptor<List<String>>()
@@ -174,20 +172,6 @@
     }
 
     @Test
-    fun testRSSISlot_combined() {
-        `when`(featureFlags.isEnabled(Flags.COMBINED_STATUS_BAR_SIGNAL_ICONS)).thenReturn(true)
-        controller.init()
-
-        val captor = argumentCaptor<List<String>>()
-        verify(view).onAttach(any(), any(), capture(captor), any(), anyBoolean())
-
-        assertThat(captor.value).containsExactly(
-            mContext.getString(com.android.internal.R.string.status_bar_no_calling),
-            mContext.getString(com.android.internal.R.string.status_bar_call_strength)
-        )
-    }
-
-    @Test
     fun testSingleCarrierCallback() {
         controller.init()
         reset(view)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java
index bd794d6..1963e30 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java
@@ -37,7 +37,6 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.CarrierTextManager;
-import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.connectivity.IconState;
 import com.android.systemui.statusbar.connectivity.MobileDataIndicators;
@@ -80,7 +79,6 @@
     @Mock
     private QSCarrier mQSCarrier3;
     private TestableLooper mTestableLooper;
-    @Mock private FeatureFlags mFeatureFlags;
     @Mock
     private QSCarrierGroupController.OnSingleCarrierChangedListener mOnSingleCarrierChangedListener;
 
@@ -120,7 +118,7 @@
         mQSCarrierGroupController = new QSCarrierGroupController.Builder(
                 mActivityStarter, handler, TestableLooper.get(this).getLooper(),
                 mNetworkController, mCarrierTextControllerBuilder, mContext, mCarrierConfigTracker,
-                mFeatureFlags, mSlotIndexResolver)
+                mSlotIndexResolver)
                 .setQSCarrierGroup(mQSCarrierGroup)
                 .build();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierTest.java
index 5212255..99a17a6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierTest.java
@@ -22,13 +22,11 @@
 
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
-import android.util.FeatureFlagUtils;
 import android.view.LayoutInflater;
 import android.view.View;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.settingslib.graph.SignalDrawable;
 import com.android.settingslib.mobile.TelephonyIcons;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
@@ -59,14 +57,14 @@
 
     @Test
     public void testUpdateState_first() {
-        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false, false);
+        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false);
 
         assertTrue(mQSCarrier.updateState(c, false));
     }
 
     @Test
     public void testUpdateState_same() {
-        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false, false);
+        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false);
 
         assertTrue(mQSCarrier.updateState(c, false));
         assertFalse(mQSCarrier.updateState(c, false));
@@ -74,7 +72,7 @@
 
     @Test
     public void testUpdateState_changed() {
-        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false, false);
+        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false);
 
         assertTrue(mQSCarrier.updateState(c, false));
 
@@ -85,14 +83,14 @@
 
     @Test
     public void testUpdateState_singleCarrier_first() {
-        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false, false);
+        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false);
 
         assertTrue(mQSCarrier.updateState(c, true));
     }
 
     @Test
     public void testUpdateState_singleCarrier_noShowIcon() {
-        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false, false);
+        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false);
 
         mQSCarrier.updateState(c, true);
 
@@ -101,7 +99,7 @@
 
     @Test
     public void testUpdateState_multiCarrier_showIcon() {
-        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false, false);
+        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false);
 
         mQSCarrier.updateState(c, false);
 
@@ -110,7 +108,7 @@
 
     @Test
     public void testUpdateState_changeSingleMultiSingle() {
-        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false, false);
+        CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false);
 
         mQSCarrier.updateState(c, true);
         assertEquals(View.GONE, mQSCarrier.getRSSIView().getVisibility());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
index 3d53062..d42cbe3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
@@ -55,6 +55,6 @@
     @Test
     public void testResetNotifiesHost() {
         mTileAdapter.resetTileSpecs(Collections.emptyList());
-        verify(mQSTileHost).changeTiles(any(), any());
+        verify(mQSTileHost).changeTilesByUser(any(), any());
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt
index 2ad9c94..fb17fc0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt
@@ -163,4 +163,20 @@
         assertThat(tile.isClickable).isFalse()
         assertThat(tile.isLongClickable).isFalse()
     }
-}
\ No newline at end of file
+
+    @Test
+    fun setTileData_tileHasCorrectContentDescription() {
+        val icon = Icon.createWithResource(mContext, R.drawable.cloud)
+        val tileData = TileRequestDialog.TileData(APP_NAME, LABEL, icon)
+
+        dialog.setTileData(tileData)
+        dialog.show()
+
+        TestableLooper.get(this).processAllMessages()
+
+        val content = dialog.requireViewById<ViewGroup>(TileRequestDialog.CONTENT_ID)
+        val tile = content.getChildAt(1) as QSTileView
+
+        assertThat(tile.contentDescription).isEqualTo(LABEL)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
index 6b7e5b93..471ddfd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
@@ -29,6 +29,7 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.os.Handler;
+import android.os.HandlerExecutor;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.service.quicksettings.IQSTileService;
@@ -65,6 +66,7 @@
 
 import java.util.ArrayList;
 import java.util.Optional;
+import java.util.concurrent.Executor;
 
 import javax.inject.Provider;
 
@@ -130,17 +132,16 @@
                 .thenReturn(mTileLifecycleManager);
 
         Provider<Handler> provider = () -> new Handler(mTestableLooper.getLooper());
+        Executor executor = new HandlerExecutor(provider.get());
 
         QSTileHost host = new QSTileHost(mContext,
                 mStatusBarIconController,
                 mQSFactory,
-                provider.get(),
-                mTestableLooper.getLooper(),
+                executor,
                 mPluginManager,
                 mTunerService,
                 () -> mAutoTileManager,
                 mDumpManager,
-                mock(BroadcastDispatcher.class),
                 Optional.of(mCentralSurfaces),
                 mQSLogger,
                 mUiEventLogger,
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/shade/CombinedShadeHeaderConstraintsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
new file mode 100644
index 0000000..0ce9056
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
@@ -0,0 +1,328 @@
+/*
+ * 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.shade
+
+import android.testing.AndroidTestingRunner
+import androidx.constraintlayout.widget.ConstraintSet
+import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
+import androidx.constraintlayout.widget.ConstraintSet.START
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class CombinedShadeHeaderConstraintsTest : SysuiTestCase() {
+
+    private lateinit var qqsConstraint: ConstraintSet
+    private lateinit var qsConstraint: ConstraintSet
+    private lateinit var largeScreenConstraint: ConstraintSet
+
+    @Before
+    fun setUp() {
+        qqsConstraint = ConstraintSet().apply {
+            load(context, context.resources.getXml(R.xml.qqs_header))
+        }
+        qsConstraint = ConstraintSet().apply {
+            load(context, context.resources.getXml(R.xml.qs_header_new))
+        }
+        largeScreenConstraint = ConstraintSet().apply {
+            load(context, context.resources.getXml(R.xml.large_screen_shade_header))
+        }
+    }
+
+    @Test
+    fun testEdgeElementsAlignedWithGuide_qqs() {
+        with(qqsConstraint) {
+            assertThat(getConstraint(R.id.clock).layout.startToStart).isEqualTo(R.id.begin_guide)
+            assertThat(getConstraint(R.id.clock).layout.horizontalBias).isEqualTo(0f)
+
+            assertThat(getConstraint(R.id.batteryRemainingIcon).layout.endToEnd)
+                .isEqualTo(R.id.end_guide)
+            assertThat(getConstraint(R.id.batteryRemainingIcon).layout.horizontalBias)
+                .isEqualTo(1f)
+
+            assertThat(getConstraint(R.id.privacy_container).layout.endToEnd)
+                .isEqualTo(R.id.end_guide)
+            assertThat(getConstraint(R.id.privacy_container).layout.horizontalBias)
+                .isEqualTo(1f)
+        }
+    }
+
+    @Test
+    fun testClockScale() {
+        with(qqsConstraint.getConstraint(R.id.clock)) {
+            assertThat(transform.scaleX).isEqualTo(1f)
+            assertThat(transform.scaleY).isEqualTo(1f)
+        }
+        with(qsConstraint.getConstraint(R.id.clock)) {
+            assertThat(transform.scaleX).isGreaterThan(1f)
+            assertThat(transform.scaleY).isGreaterThan(1f)
+        }
+    }
+
+    @Test
+    fun testEdgeElementsAlignedWithEdgeOrGuide_qs() {
+        with(qsConstraint) {
+            assertThat(getConstraint(R.id.clock).layout.startToStart).isEqualTo(PARENT_ID)
+            assertThat(getConstraint(R.id.clock).layout.horizontalBias).isEqualTo(0f)
+
+            assertThat(getConstraint(R.id.date).layout.startToStart).isEqualTo(PARENT_ID)
+            assertThat(getConstraint(R.id.date).layout.horizontalBias).isEqualTo(0f)
+
+            assertThat(getConstraint(R.id.batteryRemainingIcon).layout.endToEnd)
+                .isEqualTo(PARENT_ID)
+            assertThat(getConstraint(R.id.batteryRemainingIcon).layout.horizontalBias)
+                .isEqualTo(1f)
+
+            assertThat(getConstraint(R.id.privacy_container).layout.endToEnd)
+                .isEqualTo(R.id.end_guide)
+            assertThat(getConstraint(R.id.privacy_container).layout.horizontalBias).isEqualTo(1f)
+        }
+    }
+
+    @Test
+    fun testEdgeElementsAlignedWithEdge_largeScreen() {
+        with(largeScreenConstraint) {
+            assertThat(getConstraint(R.id.clock).layout.startToStart).isEqualTo(PARENT_ID)
+            assertThat(getConstraint(R.id.clock).layout.horizontalBias).isEqualTo(0f)
+
+            assertThat(getConstraint(R.id.privacy_container).layout.endToEnd).isEqualTo(PARENT_ID)
+            assertThat(getConstraint(R.id.privacy_container).layout.horizontalBias).isEqualTo(1f)
+        }
+    }
+
+    @Test
+    fun testCarrierAlpha() {
+        assertThat(qqsConstraint.getConstraint(R.id.carrier_group).propertySet.alpha).isEqualTo(0f)
+        assertThat(qsConstraint.getConstraint(R.id.carrier_group).propertySet.alpha).isEqualTo(1f)
+        assertThat(largeScreenConstraint.getConstraint(R.id.carrier_group).propertySet.alpha)
+            .isEqualTo(1f)
+    }
+
+    @Test
+    fun testPrivacyChipVisibilityConstraints_notVisible() {
+        val changes = CombinedShadeHeadersConstraintManagerImpl
+            .privacyChipVisibilityConstraints(false)
+        changes()
+
+        with(qqsConstraint) {
+            assertThat(getConstraint(R.id.statusIcons).propertySet.alpha).isEqualTo(1f)
+            assertThat(getConstraint(R.id.batteryRemainingIcon).propertySet.alpha).isEqualTo(1f)
+        }
+
+        with(qsConstraint) {
+            assertThat(getConstraint(R.id.statusIcons).propertySet.alpha).isEqualTo(1f)
+            assertThat(getConstraint(R.id.batteryRemainingIcon).propertySet.alpha).isEqualTo(1f)
+        }
+
+        with(largeScreenConstraint) {
+            assertThat(getConstraint(R.id.statusIcons).propertySet.alpha).isEqualTo(1f)
+            assertThat(getConstraint(R.id.batteryRemainingIcon).propertySet.alpha).isEqualTo(1f)
+        }
+    }
+
+    @Test
+    fun testPrivacyChipVisibilityConstraints_visible() {
+        val changes = CombinedShadeHeadersConstraintManagerImpl
+            .privacyChipVisibilityConstraints(true)
+        changes()
+
+        with(qqsConstraint) {
+            assertThat(getConstraint(R.id.statusIcons).propertySet.alpha).isEqualTo(0f)
+            assertThat(getConstraint(R.id.batteryRemainingIcon).propertySet.alpha).isEqualTo(0f)
+        }
+
+        with(qsConstraint) {
+            assertThat(getConstraint(R.id.statusIcons).propertySet.alpha).isEqualTo(1f)
+            assertThat(getConstraint(R.id.batteryRemainingIcon).propertySet.alpha).isEqualTo(1f)
+        }
+
+        with(largeScreenConstraint) {
+            assertThat(getConstraint(R.id.statusIcons).propertySet.alpha).isEqualTo(1f)
+            assertThat(getConstraint(R.id.batteryRemainingIcon).propertySet.alpha).isEqualTo(1f)
+        }
+    }
+
+    @Test
+    fun testEmptyCutoutConstraints() {
+        val changes = CombinedShadeHeadersConstraintManagerImpl.emptyCutoutConstraints()
+        changes()
+
+        // QS and Large Screen don't change with cutouts.
+        assertThat(changes.qsConstraintsChanges).isNull()
+        assertThat(changes.largeScreenConstraintsChanges).isNull()
+
+        with(qqsConstraint) {
+            // In this case, the date is constrained on the end by a Barrier determined by either
+            // privacy or statusIcons
+            assertThat(getConstraint(R.id.date).layout.endToStart).isEqualTo(R.id.barrier)
+            assertThat(getConstraint(R.id.statusIcons).layout.startToEnd).isEqualTo(R.id.date)
+            assertThat(getConstraint(R.id.privacy_container).layout.startToEnd).isEqualTo(R.id.date)
+            assertThat(getConstraint(R.id.barrier).layout.mReferenceIds).asList().containsExactly(
+                R.id.statusIcons,
+                R.id.privacy_container
+            )
+            assertThat(getConstraint(R.id.barrier).layout.mBarrierDirection).isEqualTo(START)
+        }
+    }
+
+    @Test
+    fun testGuidesAreSetInCorrectPosition_largeCutoutSmallerPadding() {
+        val cutoutStart = 100
+        val padding = 10
+        val cutoutEnd = 30
+        val changes = CombinedShadeHeadersConstraintManagerImpl.edgesGuidelinesConstraints(
+            cutoutStart,
+            padding,
+            cutoutEnd,
+            padding
+        )
+        changes()
+
+        with(qqsConstraint) {
+            assertThat(getConstraint(R.id.begin_guide).layout.guideBegin)
+                .isEqualTo(cutoutStart - padding)
+            assertThat(getConstraint(R.id.end_guide).layout.guideEnd)
+                .isEqualTo(cutoutEnd - padding)
+        }
+
+        with(qsConstraint) {
+            assertThat(getConstraint(R.id.begin_guide).layout.guideBegin)
+                .isEqualTo(cutoutStart - padding)
+            assertThat(getConstraint(R.id.end_guide).layout.guideEnd)
+                .isEqualTo(cutoutEnd - padding)
+        }
+
+        assertThat(changes.largeScreenConstraintsChanges).isNull()
+    }
+
+    @Test
+    fun testGuidesAreSetInCorrectPosition_smallCutoutLargerPadding() {
+        val cutoutStart = 5
+        val padding = 10
+        val cutoutEnd = 10
+
+        val changes = CombinedShadeHeadersConstraintManagerImpl.edgesGuidelinesConstraints(
+            cutoutStart,
+            padding,
+            cutoutEnd,
+            padding
+        )
+        changes()
+
+        with(qqsConstraint) {
+            assertThat(getConstraint(R.id.begin_guide).layout.guideBegin).isEqualTo(0)
+            assertThat(getConstraint(R.id.end_guide).layout.guideEnd).isEqualTo(0)
+        }
+
+        with(qsConstraint) {
+            assertThat(getConstraint(R.id.begin_guide).layout.guideBegin).isEqualTo(0)
+            assertThat(getConstraint(R.id.end_guide).layout.guideEnd).isEqualTo(0)
+        }
+
+        assertThat(changes.largeScreenConstraintsChanges).isNull()
+    }
+
+    @Test
+    fun testCenterCutoutConstraints_ltr() {
+        val offsetFromEdge = 400
+        val rtl = false
+
+        val changes = CombinedShadeHeadersConstraintManagerImpl
+            .centerCutoutConstraints(rtl, offsetFromEdge)
+        changes()
+
+        // In LTR, center_left is towards the start and center_right is towards the end
+        with(qqsConstraint) {
+            assertThat(getConstraint(R.id.center_left).layout.guideBegin).isEqualTo(offsetFromEdge)
+            assertThat(getConstraint(R.id.center_right).layout.guideEnd).isEqualTo(offsetFromEdge)
+            assertThat(getConstraint(R.id.date).layout.endToStart).isEqualTo(R.id.center_left)
+            assertThat(getConstraint(R.id.statusIcons).layout.startToEnd)
+                .isEqualTo(R.id.center_right)
+            assertThat(getConstraint(R.id.privacy_container).layout.startToEnd)
+                .isEqualTo(R.id.center_right)
+        }
+
+        with(qsConstraint) {
+            assertThat(getConstraint(R.id.center_left).layout.guideBegin).isEqualTo(offsetFromEdge)
+            assertThat(getConstraint(R.id.center_right).layout.guideEnd).isEqualTo(offsetFromEdge)
+
+            assertThat(getConstraint(R.id.date).layout.endToStart).isNotEqualTo(R.id.center_left)
+            assertThat(getConstraint(R.id.date).layout.endToStart).isNotEqualTo(R.id.center_right)
+
+            assertThat(getConstraint(R.id.statusIcons).layout.startToEnd)
+                .isNotEqualTo(R.id.center_left)
+            assertThat(getConstraint(R.id.statusIcons).layout.startToEnd)
+                .isNotEqualTo(R.id.center_right)
+
+            assertThat(getConstraint(R.id.privacy_container).layout.startToEnd)
+                .isEqualTo(R.id.center_right)
+        }
+
+        assertThat(changes.largeScreenConstraintsChanges).isNull()
+    }
+
+    @Test
+    fun testCenterCutoutConstraints_rtl() {
+        val offsetFromEdge = 400
+        val rtl = true
+
+        val changes = CombinedShadeHeadersConstraintManagerImpl
+            .centerCutoutConstraints(rtl, offsetFromEdge)
+        changes()
+
+        // In RTL, center_left is towards the end and center_right is towards the start
+        with(qqsConstraint) {
+            assertThat(getConstraint(R.id.center_left).layout.guideEnd).isEqualTo(offsetFromEdge)
+            assertThat(getConstraint(R.id.center_right).layout.guideBegin).isEqualTo(offsetFromEdge)
+            assertThat(getConstraint(R.id.date).layout.endToStart).isEqualTo(R.id.center_right)
+            assertThat(getConstraint(R.id.statusIcons).layout.startToEnd)
+                .isEqualTo(R.id.center_left)
+            assertThat(getConstraint(R.id.privacy_container).layout.startToEnd)
+                .isEqualTo(R.id.center_left)
+        }
+
+        with(qsConstraint) {
+            assertThat(getConstraint(R.id.center_left).layout.guideEnd).isEqualTo(offsetFromEdge)
+            assertThat(getConstraint(R.id.center_right).layout.guideBegin).isEqualTo(offsetFromEdge)
+
+            assertThat(getConstraint(R.id.date).layout.endToStart).isNotEqualTo(R.id.center_left)
+            assertThat(getConstraint(R.id.date).layout.endToStart).isNotEqualTo(R.id.center_right)
+
+            assertThat(getConstraint(R.id.statusIcons).layout.startToEnd)
+                .isNotEqualTo(R.id.center_left)
+            assertThat(getConstraint(R.id.statusIcons).layout.startToEnd)
+                .isNotEqualTo(R.id.center_right)
+
+            assertThat(getConstraint(R.id.privacy_container).layout.startToEnd)
+                .isEqualTo(R.id.center_left)
+        }
+
+        assertThat(changes.largeScreenConstraintsChanges).isNull()
+    }
+
+    private operator fun ConstraintsChanges.invoke() {
+        qqsConstraintsChanges?.invoke(qqsConstraint)
+        qsConstraintsChanges?.invoke(qsConstraint)
+        largeScreenConstraintsChanges?.invoke(largeScreenConstraint)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangeTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangeTest.kt
new file mode 100644
index 0000000..9b2e085
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangeTest.kt
@@ -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.systemui.shade
+
+import android.testing.AndroidTestingRunner
+import androidx.constraintlayout.widget.ConstraintSet
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.inOrder
+import org.mockito.Mockito.verify
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class ConstraintChangeTest : SysuiTestCase() {
+
+    @Test
+    fun testSumNonNull() {
+        val mock1: ConstraintChange = mock()
+        val mock2: ConstraintChange = mock()
+
+        val constraintSet = ConstraintSet()
+
+        val sum = mock1 + mock2
+        sum?.invoke(constraintSet)
+
+        val inOrder = inOrder(mock1, mock2)
+        inOrder.verify(mock1).invoke(constraintSet)
+        inOrder.verify(mock2).invoke(constraintSet)
+    }
+
+    @Test
+    fun testSumThisNull() {
+        val mock: ConstraintChange = mock()
+        val constraintSet = ConstraintSet()
+
+        val sum = (null as? ConstraintChange?) + mock
+        sum?.invoke(constraintSet)
+
+        verify(mock).invoke(constraintSet)
+    }
+
+    @Test
+    fun testSumThisNull_notWrapped() {
+        val change: ConstraintChange = {}
+
+        val sum = (null as? ConstraintChange?) + change
+        assertThat(sum).isSameInstanceAs(change)
+    }
+
+    @Test
+    fun testSumOtherNull() {
+        val mock: ConstraintChange = mock()
+        val constraintSet = ConstraintSet()
+
+        val sum = mock + (null as? ConstraintChange?)
+        sum?.invoke(constraintSet)
+
+        verify(mock).invoke(constraintSet)
+    }
+
+    @Test
+    fun testSumOtherNull_notWrapped() {
+        val change: ConstraintChange = {}
+
+        val sum = change + (null as? ConstraintChange?)
+        assertThat(sum).isSameInstanceAs(change)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangesTest.kt
new file mode 100644
index 0000000..0abb084
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangesTest.kt
@@ -0,0 +1,75 @@
+/*
+ * 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.shade
+
+import android.testing.AndroidTestingRunner
+import androidx.constraintlayout.widget.ConstraintSet
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.inOrder
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class ConstraintChangesTest : SysuiTestCase() {
+
+    @Test
+    fun testSumWithoutNulls() {
+        val mockQQS1: ConstraintChange = mock()
+        val mockQS1: ConstraintChange = mock()
+        val mockLS1: ConstraintChange = mock()
+        val mockQQS2: ConstraintChange = mock()
+        val mockQS2: ConstraintChange = mock()
+        val mockLS2: ConstraintChange = mock()
+
+        val changes1 = ConstraintsChanges(mockQQS1, mockQS1, mockLS1)
+        val changes2 = ConstraintsChanges(mockQQS2, mockQS2, mockLS2)
+
+        val sum = changes1 + changes2
+
+        val constraintSet = ConstraintSet()
+        sum.qqsConstraintsChanges?.invoke(constraintSet)
+        sum.qsConstraintsChanges?.invoke(constraintSet)
+        sum.largeScreenConstraintsChanges?.invoke(constraintSet)
+
+        val inOrder = inOrder(mockQQS1, mockQS1, mockLS1, mockQQS2, mockQS2, mockLS2)
+
+        inOrder.verify(mockQQS1).invoke(constraintSet)
+        inOrder.verify(mockQQS2).invoke(constraintSet)
+        inOrder.verify(mockQS1).invoke(constraintSet)
+        inOrder.verify(mockQS2).invoke(constraintSet)
+        inOrder.verify(mockLS1).invoke(constraintSet)
+        inOrder.verify(mockLS2).invoke(constraintSet)
+    }
+
+    @Test
+    fun testSumWithSomeNulls() {
+        val mockQQS: ConstraintChange = mock()
+        val mockQS: ConstraintChange = mock()
+
+        val changes1 = ConstraintsChanges(mockQQS, null, null)
+        val changes2 = ConstraintsChanges(null, mockQS, null)
+
+        val sum = changes1 + changes2
+
+        assertThat(sum.qqsConstraintsChanges).isSameInstanceAs(mockQQS)
+        assertThat(sum.qsConstraintsChanges).isSameInstanceAs(mockQS)
+        assertThat(sum.largeScreenConstraintsChanges).isNull()
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
new file mode 100644
index 0000000..ed1a13b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
@@ -0,0 +1,659 @@
+/*
+ * 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.shade
+
+import android.content.Context
+import android.content.res.Resources
+import android.content.res.XmlResourceParser
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import android.view.DisplayCutout
+import android.view.View
+import android.view.WindowInsets
+import android.widget.TextView
+import androidx.constraintlayout.motion.widget.MotionLayout
+import androidx.constraintlayout.widget.ConstraintSet
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.ShadeInterpolation
+import com.android.systemui.battery.BatteryMeterView
+import com.android.systemui.battery.BatteryMeterViewController
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.qs.ChipVisibilityListener
+import com.android.systemui.qs.HeaderPrivacyIconsController
+import com.android.systemui.qs.carrier.QSCarrierGroup
+import com.android.systemui.qs.carrier.QSCarrierGroupController
+import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.HEADER_TRANSITION_ID
+import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.LARGE_SCREEN_HEADER_CONSTRAINT
+import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.LARGE_SCREEN_HEADER_TRANSITION_ID
+import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QQS_HEADER_CONSTRAINT
+import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QS_HEADER_CONSTRAINT
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
+import com.android.systemui.statusbar.phone.StatusBarIconController
+import com.android.systemui.statusbar.phone.StatusIconContainer
+import com.android.systemui.statusbar.policy.FakeConfigurationController
+import com.android.systemui.statusbar.policy.VariableDateView
+import com.android.systemui.statusbar.policy.VariableDateViewController
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Answers
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers
+import org.mockito.Mock
+import org.mockito.Mockito.anyBoolean
+import org.mockito.Mockito.anyFloat
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.inOrder
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.junit.MockitoJUnit
+
+private val EMPTY_CHANGES = ConstraintsChanges()
+
+/**
+ * Tests for [LargeScreenShadeHeaderController] when [Flags.COMBINED_QS_HEADERS] is `true`.
+ *
+ * Once that flag is removed, this class will be combined with
+ * [LargeScreenShadeHeaderControllerTest].
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() {
+
+    @Mock
+    private lateinit var statusIcons: StatusIconContainer
+    @Mock
+    private lateinit var statusBarIconController: StatusBarIconController
+    @Mock
+    private lateinit var qsCarrierGroupController: QSCarrierGroupController
+    @Mock
+    private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder
+    @Mock
+    private lateinit var featureFlags: FeatureFlags
+    @Mock
+    private lateinit var clock: TextView
+    @Mock
+    private lateinit var date: VariableDateView
+    @Mock
+    private lateinit var carrierGroup: QSCarrierGroup
+    @Mock
+    private lateinit var batteryMeterView: BatteryMeterView
+    @Mock
+    private lateinit var batteryMeterViewController: BatteryMeterViewController
+    @Mock
+    private lateinit var privacyIconsController: HeaderPrivacyIconsController
+    @Mock
+    private lateinit var insetsProvider: StatusBarContentInsetsProvider
+    @Mock
+    private lateinit var variableDateViewControllerFactory: VariableDateViewController.Factory
+    @Mock
+    private lateinit var variableDateViewController: VariableDateViewController
+    @Mock
+    private lateinit var dumpManager: DumpManager
+    @Mock
+    private lateinit var combinedShadeHeadersConstraintManager:
+        CombinedShadeHeadersConstraintManager
+
+    @Mock
+    private lateinit var mockedContext: Context
+    @Mock(answer = Answers.RETURNS_MOCKS)
+    private lateinit var view: MotionLayout
+
+    @Mock
+    private lateinit var qqsConstraints: ConstraintSet
+    @Mock
+    private lateinit var qsConstraints: ConstraintSet
+    @Mock
+    private lateinit var largeScreenConstraints: ConstraintSet
+
+    @JvmField @Rule
+    val mockitoRule = MockitoJUnit.rule()
+    var viewVisibility = View.GONE
+
+    private lateinit var controller: LargeScreenShadeHeaderController
+    private lateinit var carrierIconSlots: List<String>
+    private val configurationController = FakeConfigurationController()
+
+    @Before
+    fun setUp() {
+        whenever<TextView>(view.findViewById(R.id.clock)).thenReturn(clock)
+        whenever(clock.context).thenReturn(mockedContext)
+
+        whenever<TextView>(view.findViewById(R.id.date)).thenReturn(date)
+        whenever(date.context).thenReturn(mockedContext)
+        whenever(variableDateViewControllerFactory.create(any()))
+            .thenReturn(variableDateViewController)
+
+        whenever<QSCarrierGroup>(view.findViewById(R.id.carrier_group)).thenReturn(carrierGroup)
+        whenever<BatteryMeterView>(view.findViewById(R.id.batteryRemainingIcon))
+            .thenReturn(batteryMeterView)
+
+        whenever<StatusIconContainer>(view.findViewById(R.id.statusIcons)).thenReturn(statusIcons)
+        whenever(statusIcons.context).thenReturn(context)
+
+        whenever(qsCarrierGroupControllerBuilder.setQSCarrierGroup(any()))
+            .thenReturn(qsCarrierGroupControllerBuilder)
+        whenever(qsCarrierGroupControllerBuilder.build()).thenReturn(qsCarrierGroupController)
+
+        whenever(view.context).thenReturn(context)
+        whenever(view.resources).thenReturn(context.resources)
+        whenever(view.setVisibility(ArgumentMatchers.anyInt())).then {
+            viewVisibility = it.arguments[0] as Int
+            null
+        }
+        whenever(view.visibility).thenAnswer { _ -> viewVisibility }
+
+        whenever(featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)).thenReturn(true)
+        whenever(featureFlags.isEnabled(Flags.NEW_HEADER)).thenReturn(true)
+
+        setUpDefaultInsets()
+        setUpMotionLayout(view)
+
+        controller = LargeScreenShadeHeaderController(
+            view,
+            statusBarIconController,
+            privacyIconsController,
+            insetsProvider,
+            configurationController,
+            variableDateViewControllerFactory,
+            batteryMeterViewController,
+            dumpManager,
+            featureFlags,
+            qsCarrierGroupControllerBuilder,
+            combinedShadeHeadersConstraintManager
+        )
+        whenever(view.isAttachedToWindow).thenReturn(true)
+        controller.init()
+        carrierIconSlots = listOf(
+            context.getString(com.android.internal.R.string.status_bar_mobile))
+    }
+
+    @Test
+    fun testCorrectConstraints() {
+        val captor = ArgumentCaptor.forClass(XmlResourceParser::class.java)
+
+        verify(qqsConstraints).load(eq(context), capture(captor))
+        assertThat(captor.value.getResId()).isEqualTo(R.xml.qqs_header)
+
+        verify(qsConstraints).load(eq(context), capture(captor))
+        assertThat(captor.value.getResId()).isEqualTo(R.xml.qs_header_new)
+
+        verify(largeScreenConstraints).load(eq(context), capture(captor))
+        assertThat(captor.value.getResId()).isEqualTo(R.xml.large_screen_shade_header)
+    }
+
+    @Test
+    fun testControllersCreatedAndInitialized() {
+        verify(variableDateViewController).init()
+
+        verify(batteryMeterViewController).init()
+        verify(batteryMeterViewController).ignoreTunerUpdates()
+        verify(batteryMeterView).setPercentShowMode(BatteryMeterView.MODE_ESTIMATE)
+
+        val inOrder = inOrder(qsCarrierGroupControllerBuilder)
+        inOrder.verify(qsCarrierGroupControllerBuilder).setQSCarrierGroup(carrierGroup)
+        inOrder.verify(qsCarrierGroupControllerBuilder).build()
+    }
+
+    @Test
+    fun testClockPivotLtr() {
+        val width = 200
+        whenever(clock.width).thenReturn(width)
+        whenever(clock.isLayoutRtl).thenReturn(false)
+
+        val captor = ArgumentCaptor.forClass(View.OnLayoutChangeListener::class.java)
+        verify(clock).addOnLayoutChangeListener(capture(captor))
+
+        captor.value.onLayoutChange(clock, 0, 1, 2, 3, 4, 5, 6, 7)
+        verify(clock).pivotX = 0f
+    }
+
+    @Test
+    fun testClockPivotRtl() {
+        val width = 200
+        whenever(clock.width).thenReturn(width)
+        whenever(clock.isLayoutRtl).thenReturn(true)
+
+        val captor = ArgumentCaptor.forClass(View.OnLayoutChangeListener::class.java)
+        verify(clock).addOnLayoutChangeListener(capture(captor))
+
+        captor.value.onLayoutChange(clock, 0, 1, 2, 3, 4, 5, 6, 7)
+        verify(clock).pivotX = width.toFloat()
+    }
+
+    @Test
+    fun testShadeExpanded_true() {
+        // When shade is expanded, view should be visible regardless of largeScreenActive
+        controller.largeScreenActive = false
+        controller.qsVisible = true
+        assertThat(viewVisibility).isEqualTo(View.VISIBLE)
+
+        controller.largeScreenActive = true
+        assertThat(viewVisibility).isEqualTo(View.VISIBLE)
+    }
+
+    @Test
+    fun testShadeExpanded_false() {
+        // When shade is not expanded, view should be invisible regardless of largeScreenActive
+        controller.largeScreenActive = false
+        controller.qsVisible = false
+        assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
+
+        controller.largeScreenActive = true
+        assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
+    }
+
+    @Test
+    fun testLargeScreenActive_true() {
+        controller.largeScreenActive = false // Make sure there's a change
+        clearInvocations(view)
+
+        controller.largeScreenActive = true
+
+        verify(view).setTransition(LARGE_SCREEN_HEADER_TRANSITION_ID)
+    }
+
+    @Test
+    fun testLargeScreenActive_false() {
+        controller.largeScreenActive = true // Make sure there's a change
+        clearInvocations(view)
+
+        controller.largeScreenActive = false
+
+        verify(view).setTransition(HEADER_TRANSITION_ID)
+    }
+
+    @Test
+    fun testShadeExpandedFraction() {
+        // View needs to be visible for this to actually take effect
+        controller.qsVisible = true
+
+        clearInvocations(view)
+        controller.shadeExpandedFraction = 0.3f
+        verify(view).alpha = ShadeInterpolation.getContentAlpha(0.3f)
+
+        clearInvocations(view)
+        controller.shadeExpandedFraction = 1f
+        verify(view).alpha = ShadeInterpolation.getContentAlpha(1f)
+
+        clearInvocations(view)
+        controller.shadeExpandedFraction = 0f
+        verify(view).alpha = ShadeInterpolation.getContentAlpha(0f)
+    }
+
+    @Test
+    fun testQsExpandedFraction_headerTransition() {
+        controller.qsVisible = true
+        controller.largeScreenActive = false
+
+        clearInvocations(view)
+        controller.qsExpandedFraction = 0.3f
+        verify(view).progress = 0.3f
+    }
+
+    @Test
+    fun testQsExpandedFraction_largeScreen() {
+        controller.qsVisible = true
+        controller.largeScreenActive = true
+
+        clearInvocations(view)
+        controller.qsExpandedFraction = 0.3f
+        verify(view, never()).progress = anyFloat()
+    }
+
+    @Test
+    fun testScrollY_headerTransition() {
+        controller.largeScreenActive = false
+
+        clearInvocations(view)
+        controller.qsScrollY = 20
+        verify(view).scrollY = 20
+    }
+
+    @Test
+    fun testScrollY_largeScreen() {
+        controller.largeScreenActive = true
+
+        clearInvocations(view)
+        controller.qsScrollY = 20
+        verify(view, never()).scrollY = anyInt()
+    }
+
+    @Test
+    fun testPrivacyChipVisibilityChanged_visible_changesCorrectConstraints() {
+        val chipVisibleChanges = createMockConstraintChanges()
+        val chipNotVisibleChanges = createMockConstraintChanges()
+
+        whenever(combinedShadeHeadersConstraintManager.privacyChipVisibilityConstraints(true))
+            .thenReturn(chipVisibleChanges)
+        whenever(combinedShadeHeadersConstraintManager.privacyChipVisibilityConstraints(false))
+            .thenReturn(chipNotVisibleChanges)
+
+        val captor = ArgumentCaptor.forClass(ChipVisibilityListener::class.java)
+        verify(privacyIconsController).chipVisibilityListener = capture(captor)
+
+        captor.value.onChipVisibilityRefreshed(true)
+
+        verify(chipVisibleChanges.qqsConstraintsChanges)!!.invoke(qqsConstraints)
+        verify(chipVisibleChanges.qsConstraintsChanges)!!.invoke(qsConstraints)
+        verify(chipVisibleChanges.largeScreenConstraintsChanges)!!.invoke(largeScreenConstraints)
+
+        verify(chipNotVisibleChanges.qqsConstraintsChanges, never())!!.invoke(any())
+        verify(chipNotVisibleChanges.qsConstraintsChanges, never())!!.invoke(any())
+        verify(chipNotVisibleChanges.largeScreenConstraintsChanges, never())!!.invoke(any())
+    }
+
+    @Test
+    fun testPrivacyChipVisibilityChanged_notVisible_changesCorrectConstraints() {
+        val chipVisibleChanges = createMockConstraintChanges()
+        val chipNotVisibleChanges = createMockConstraintChanges()
+
+        whenever(combinedShadeHeadersConstraintManager.privacyChipVisibilityConstraints(true))
+            .thenReturn(chipVisibleChanges)
+        whenever(combinedShadeHeadersConstraintManager.privacyChipVisibilityConstraints(false))
+            .thenReturn(chipNotVisibleChanges)
+
+        val captor = ArgumentCaptor.forClass(ChipVisibilityListener::class.java)
+        verify(privacyIconsController).chipVisibilityListener = capture(captor)
+
+        captor.value.onChipVisibilityRefreshed(false)
+
+        verify(chipVisibleChanges.qqsConstraintsChanges, never())!!.invoke(qqsConstraints)
+        verify(chipVisibleChanges.qsConstraintsChanges, never())!!.invoke(qsConstraints)
+        verify(chipVisibleChanges.largeScreenConstraintsChanges, never())!!
+            .invoke(largeScreenConstraints)
+
+        verify(chipNotVisibleChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(chipNotVisibleChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(chipNotVisibleChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun testInsetsGuides_ltr() {
+        whenever(view.isLayoutRtl).thenReturn(false)
+        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
+        verify(view).setOnApplyWindowInsetsListener(capture(captor))
+        val mockConstraintsChanges = createMockConstraintChanges()
+
+        val (insetLeft, insetRight) = 30 to 40
+        val (paddingStart, paddingEnd) = 10 to 20
+        whenever(view.paddingStart).thenReturn(paddingStart)
+        whenever(view.paddingEnd).thenReturn(paddingEnd)
+
+        mockInsetsProvider(insetLeft to insetRight, false)
+
+        whenever(combinedShadeHeadersConstraintManager
+            .edgesGuidelinesConstraints(anyInt(), anyInt(), anyInt(), anyInt())
+        ).thenReturn(mockConstraintsChanges)
+
+        captor.value.onApplyWindowInsets(view, createWindowInsets())
+
+        verify(combinedShadeHeadersConstraintManager)
+            .edgesGuidelinesConstraints(insetLeft, paddingStart, insetRight, paddingEnd)
+
+        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun testInsetsGuides_rtl() {
+        whenever(view.isLayoutRtl).thenReturn(true)
+        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
+        verify(view).setOnApplyWindowInsetsListener(capture(captor))
+        val mockConstraintsChanges = createMockConstraintChanges()
+
+        val (insetLeft, insetRight) = 30 to 40
+        val (paddingStart, paddingEnd) = 10 to 20
+        whenever(view.paddingStart).thenReturn(paddingStart)
+        whenever(view.paddingEnd).thenReturn(paddingEnd)
+
+        mockInsetsProvider(insetLeft to insetRight, false)
+
+        whenever(combinedShadeHeadersConstraintManager
+            .edgesGuidelinesConstraints(anyInt(), anyInt(), anyInt(), anyInt())
+        ).thenReturn(mockConstraintsChanges)
+
+        captor.value.onApplyWindowInsets(view, createWindowInsets())
+
+        verify(combinedShadeHeadersConstraintManager)
+            .edgesGuidelinesConstraints(insetRight, paddingStart, insetLeft, paddingEnd)
+
+        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun testNullCutout() {
+        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
+        verify(view).setOnApplyWindowInsetsListener(capture(captor))
+        val mockConstraintsChanges = createMockConstraintChanges()
+
+        whenever(combinedShadeHeadersConstraintManager.emptyCutoutConstraints())
+            .thenReturn(mockConstraintsChanges)
+
+        captor.value.onApplyWindowInsets(view, createWindowInsets(null))
+
+        verify(combinedShadeHeadersConstraintManager).emptyCutoutConstraints()
+        verify(combinedShadeHeadersConstraintManager, never())
+            .centerCutoutConstraints(anyBoolean(), anyInt())
+
+        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun testEmptyCutout() {
+        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
+        verify(view).setOnApplyWindowInsetsListener(capture(captor))
+        val mockConstraintsChanges = createMockConstraintChanges()
+
+        whenever(combinedShadeHeadersConstraintManager.emptyCutoutConstraints())
+            .thenReturn(mockConstraintsChanges)
+
+        captor.value.onApplyWindowInsets(view, createWindowInsets())
+
+        verify(combinedShadeHeadersConstraintManager).emptyCutoutConstraints()
+        verify(combinedShadeHeadersConstraintManager, never())
+            .centerCutoutConstraints(anyBoolean(), anyInt())
+
+        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun testCornerCutout_emptyRect() {
+        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
+        verify(view).setOnApplyWindowInsetsListener(capture(captor))
+        val mockConstraintsChanges = createMockConstraintChanges()
+
+        mockInsetsProvider(0 to 0, true)
+
+        whenever(combinedShadeHeadersConstraintManager.emptyCutoutConstraints())
+            .thenReturn(mockConstraintsChanges)
+
+        captor.value.onApplyWindowInsets(view, createWindowInsets())
+
+        verify(combinedShadeHeadersConstraintManager).emptyCutoutConstraints()
+        verify(combinedShadeHeadersConstraintManager, never())
+            .centerCutoutConstraints(anyBoolean(), anyInt())
+
+        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun testCornerCutout_nonEmptyRect() {
+        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
+        verify(view).setOnApplyWindowInsetsListener(capture(captor))
+        val mockConstraintsChanges = createMockConstraintChanges()
+
+        mockInsetsProvider(0 to 0, true)
+
+        whenever(combinedShadeHeadersConstraintManager.emptyCutoutConstraints())
+            .thenReturn(mockConstraintsChanges)
+
+        captor.value.onApplyWindowInsets(view, createWindowInsets(Rect(1, 2, 3, 4)))
+
+        verify(combinedShadeHeadersConstraintManager).emptyCutoutConstraints()
+        verify(combinedShadeHeadersConstraintManager, never())
+            .centerCutoutConstraints(anyBoolean(), anyInt())
+
+        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun testTopCutout_ltr() {
+        val width = 100
+        val paddingLeft = 10
+        val paddingRight = 20
+        val cutoutWidth = 30
+
+        whenever(view.isLayoutRtl).thenReturn(false)
+        whenever(view.width).thenReturn(width)
+        whenever(view.paddingLeft).thenReturn(paddingLeft)
+        whenever(view.paddingRight).thenReturn(paddingRight)
+
+        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
+        verify(view).setOnApplyWindowInsetsListener(capture(captor))
+        val mockConstraintsChanges = createMockConstraintChanges()
+
+        mockInsetsProvider(0 to 0, false)
+
+        whenever(combinedShadeHeadersConstraintManager
+            .centerCutoutConstraints(anyBoolean(), anyInt())
+        ).thenReturn(mockConstraintsChanges)
+
+        captor.value.onApplyWindowInsets(view, createWindowInsets(Rect(0, 0, cutoutWidth, 1)))
+
+        verify(combinedShadeHeadersConstraintManager, never()).emptyCutoutConstraints()
+        val offset = (width - paddingLeft - paddingRight - cutoutWidth) / 2
+        verify(combinedShadeHeadersConstraintManager).centerCutoutConstraints(false, offset)
+
+        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun testTopCutout_rtl() {
+        val width = 100
+        val paddingLeft = 10
+        val paddingRight = 20
+        val cutoutWidth = 30
+
+        whenever(view.isLayoutRtl).thenReturn(true)
+        whenever(view.width).thenReturn(width)
+        whenever(view.paddingLeft).thenReturn(paddingLeft)
+        whenever(view.paddingRight).thenReturn(paddingRight)
+
+        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
+        verify(view).setOnApplyWindowInsetsListener(capture(captor))
+        val mockConstraintsChanges = createMockConstraintChanges()
+
+        mockInsetsProvider(0 to 0, false)
+
+        whenever(combinedShadeHeadersConstraintManager
+            .centerCutoutConstraints(anyBoolean(), anyInt())
+        ).thenReturn(mockConstraintsChanges)
+
+        captor.value.onApplyWindowInsets(view, createWindowInsets(Rect(0, 0, cutoutWidth, 1)))
+
+        verify(combinedShadeHeadersConstraintManager, never()).emptyCutoutConstraints()
+        val offset = (width - paddingLeft - paddingRight - cutoutWidth) / 2
+        verify(combinedShadeHeadersConstraintManager).centerCutoutConstraints(true, offset)
+
+        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    private fun createWindowInsets(
+        topCutout: Rect? = Rect()
+    ): WindowInsets {
+        val windowInsets: WindowInsets = mock()
+        val displayCutout: DisplayCutout = mock()
+        whenever(windowInsets.displayCutout)
+            .thenReturn(if (topCutout != null) displayCutout else null)
+        whenever(displayCutout.boundingRectTop).thenReturn(topCutout)
+
+        return windowInsets
+    }
+
+    private fun mockInsetsProvider(
+        insets: Pair<Int, Int> = 0 to 0,
+        cornerCutout: Boolean = false,
+    ) {
+        whenever(insetsProvider.getStatusBarContentInsetsForCurrentRotation())
+            .thenReturn(insets.toAndroidPair())
+        whenever(insetsProvider.currentRotationHasCornerCutout()).thenReturn(cornerCutout)
+    }
+
+    private fun createMockConstraintChanges(): ConstraintsChanges {
+        return ConstraintsChanges(mock(), mock(), mock())
+    }
+
+    private fun XmlResourceParser.getResId(): Int {
+        return Resources.getAttributeSetSourceResId(this)
+    }
+
+    private fun setUpMotionLayout(motionLayout: MotionLayout) {
+        whenever(motionLayout.getConstraintSet(QQS_HEADER_CONSTRAINT)).thenReturn(qqsConstraints)
+        whenever(motionLayout.getConstraintSet(QS_HEADER_CONSTRAINT)).thenReturn(qsConstraints)
+        whenever(motionLayout.getConstraintSet(LARGE_SCREEN_HEADER_CONSTRAINT))
+            .thenReturn(largeScreenConstraints)
+    }
+
+    private fun setUpDefaultInsets() {
+        whenever(combinedShadeHeadersConstraintManager
+            .edgesGuidelinesConstraints(anyInt(), anyInt(), anyInt(), anyInt())
+        ).thenReturn(EMPTY_CHANGES)
+        whenever(combinedShadeHeadersConstraintManager.emptyCutoutConstraints())
+            .thenReturn(EMPTY_CHANGES)
+        whenever(combinedShadeHeadersConstraintManager
+            .centerCutoutConstraints(anyBoolean(), anyInt())
+        ).thenReturn(EMPTY_CHANGES)
+        whenever(combinedShadeHeadersConstraintManager
+            .privacyChipVisibilityConstraints(anyBoolean())
+        ).thenReturn(EMPTY_CHANGES)
+        whenever(insetsProvider.getStatusBarContentInsetsForCurrentRotation())
+            .thenReturn(Pair(0, 0).toAndroidPair())
+        whenever(insetsProvider.currentRotationHasCornerCutout()).thenReturn(false)
+    }
+
+    private fun<T, U> Pair<T, U>.toAndroidPair(): android.util.Pair<T, U> {
+        return android.util.Pair(first, second)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
similarity index 75%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderControllerTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
index 8066401..02b26db 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
@@ -1,10 +1,8 @@
-package com.android.systemui.statusbar.phone
+package com.android.systemui.shade
 
 import android.app.StatusBarManager
 import android.content.Context
-import android.content.res.TypedArray
 import android.testing.AndroidTestingRunner
-import android.util.TypedValue.COMPLEX_UNIT_PX
 import android.view.View
 import android.widget.TextView
 import androidx.test.filters.SmallTest
@@ -19,19 +17,24 @@
 import com.android.systemui.qs.HeaderPrivacyIconsController
 import com.android.systemui.qs.carrier.QSCarrierGroup
 import com.android.systemui.qs.carrier.QSCarrierGroupController
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
+import com.android.systemui.statusbar.phone.StatusBarIconController
+import com.android.systemui.statusbar.phone.StatusIconContainer
 import com.android.systemui.statusbar.policy.FakeConfigurationController
+import com.android.systemui.statusbar.policy.VariableDateViewController
+import com.android.systemui.util.mockito.any
 import com.google.common.truth.Truth.assertThat
+import org.junit.After
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers.any
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
-import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.verify
-import org.mockito.junit.MockitoJUnit
+import org.mockito.Mockito.verifyZeroInteractions
 import org.mockito.Mockito.`when` as whenever
+import org.mockito.junit.MockitoJUnit
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
@@ -49,10 +52,14 @@
     @Mock private lateinit var batteryMeterView: BatteryMeterView
     @Mock private lateinit var batteryMeterViewController: BatteryMeterViewController
     @Mock private lateinit var privacyIconsController: HeaderPrivacyIconsController
+    @Mock private lateinit var insetsProvider: StatusBarContentInsetsProvider
+    @Mock private lateinit var variableDateViewControllerFactory: VariableDateViewController.Factory
+    @Mock private lateinit var variableDateViewController: VariableDateViewController
     @Mock private lateinit var dumpManager: DumpManager
+    @Mock private lateinit var combinedShadeHeadersConstraintManager:
+        CombinedShadeHeadersConstraintManager
 
     @Mock private lateinit var mockedContext: Context
-    @Mock private lateinit var typedArray: TypedArray
 
     @JvmField @Rule val mockitoRule = MockitoJUnit.rule()
     var viewVisibility = View.GONE
@@ -65,7 +72,6 @@
     fun setup() {
         whenever<TextView>(view.findViewById(R.id.clock)).thenReturn(clock)
         whenever(clock.context).thenReturn(mockedContext)
-        whenever(mockedContext.obtainStyledAttributes(anyInt(), any())).thenReturn(typedArray)
         whenever<TextView>(view.findViewById(R.id.date)).thenReturn(date)
         whenever(date.context).thenReturn(mockedContext)
         whenever<QSCarrierGroup>(view.findViewById(R.id.carrier_group)).thenReturn(carrierGroup)
@@ -73,6 +79,7 @@
                 .thenReturn(batteryMeterView)
         whenever<StatusIconContainer>(view.findViewById(R.id.statusIcons)).thenReturn(statusIcons)
         whenever(view.context).thenReturn(context)
+        whenever(view.resources).thenReturn(context.resources)
         whenever(statusIcons.context).thenReturn(context)
         whenever(qsCarrierGroupControllerBuilder.setQSCarrierGroup(any()))
                 .thenReturn(qsCarrierGroupControllerBuilder)
@@ -82,27 +89,39 @@
             null
         }
         whenever(view.visibility).thenAnswer { _ -> viewVisibility }
+        whenever(variableDateViewControllerFactory.create(any()))
+            .thenReturn(variableDateViewController)
         whenever(featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)).thenReturn(false)
         mLargeScreenShadeHeaderController = LargeScreenShadeHeaderController(
                 view,
                 statusBarIconController,
                 privacyIconsController,
+                insetsProvider,
                 configurationController,
-                qsCarrierGroupControllerBuilder,
-                featureFlags,
+                variableDateViewControllerFactory,
                 batteryMeterViewController,
-                dumpManager
+                dumpManager,
+                featureFlags,
+                qsCarrierGroupControllerBuilder,
+                combinedShadeHeadersConstraintManager
         )
+        whenever(view.isAttachedToWindow).thenReturn(true)
+        mLargeScreenShadeHeaderController.init()
         carrierIconSlots = listOf(
                 context.getString(com.android.internal.R.string.status_bar_mobile))
     }
 
+    @After
+    fun verifyEveryTest() {
+        verifyZeroInteractions(combinedShadeHeadersConstraintManager)
+    }
+
     @Test
     fun setVisible_onlyWhenActive() {
         makeShadeVisible()
         assertThat(viewVisibility).isEqualTo(View.VISIBLE)
 
-        mLargeScreenShadeHeaderController.active = false
+        mLargeScreenShadeHeaderController.largeScreenActive = false
         assertThat(viewVisibility).isEqualTo(View.GONE)
     }
 
@@ -156,41 +175,16 @@
     }
 
     private fun makeShadeVisible() {
-        mLargeScreenShadeHeaderController.active = true
-        mLargeScreenShadeHeaderController.shadeExpanded = true
+        mLargeScreenShadeHeaderController.largeScreenActive = true
+        mLargeScreenShadeHeaderController.qsVisible = true
     }
 
     @Test
-    fun updateConfig_changesFontSize() {
-        val updatedTextPixelSize = 32
-        setReturnTextSize(updatedTextPixelSize)
-
+    fun updateConfig_changesFontStyle() {
         configurationController.notifyDensityOrFontScaleChanged()
 
-        verify(clock).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize.toFloat())
-        verify(date).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize.toFloat())
-        verify(carrierGroup).updateTextAppearance(R.style.TextAppearance_QS_Status)
-    }
-
-    @Test
-    fun updateConfig_changesFontSizeMultipleTimes() {
-        val updatedTextPixelSize1 = 32
-        setReturnTextSize(updatedTextPixelSize1)
-        configurationController.notifyDensityOrFontScaleChanged()
-        verify(clock).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize1.toFloat())
-        verify(date).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize1.toFloat())
-        verify(carrierGroup).updateTextAppearance(R.style.TextAppearance_QS_Status)
-        clearInvocations(carrierGroup)
-
-        val updatedTextPixelSize2 = 42
-        setReturnTextSize(updatedTextPixelSize2)
-        configurationController.notifyDensityOrFontScaleChanged()
-        verify(clock).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize2.toFloat())
-        verify(date).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize2.toFloat())
-        verify(carrierGroup).updateTextAppearance(R.style.TextAppearance_QS_Status)
-    }
-
-    private fun setReturnTextSize(resultTextSize: Int) {
-        whenever(typedArray.getDimensionPixelSize(anyInt(), anyInt())).thenReturn(resultTextSize)
+        verify(clock).setTextAppearance(R.style.TextAppearance_QS_Status)
+        verify(date).setTextAppearance(R.style.TextAppearance_QS_Status)
+        verify(carrierGroup).updateTextAppearance(R.style.TextAppearance_QS_Status_Carriers)
     }
 }
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 94%
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 5b0f3c4..e2673bb 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,26 @@
 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.LockscreenGestureLogger;
+import com.android.systemui.statusbar.phone.NotificationIconAreaController;
+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;
@@ -563,7 +582,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));
@@ -991,6 +1010,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);
@@ -1146,11 +1180,11 @@
         mStatusBarStateController.setState(SHADE);
         when(mResources.getBoolean(R.bool.config_use_large_screen_shade_header)).thenReturn(true);
         mNotificationPanelViewController.updateResources();
-        verify(mLargeScreenShadeHeaderController).setActive(true);
+        verify(mLargeScreenShadeHeaderController).setLargeScreenActive(true);
 
         when(mResources.getBoolean(R.bool.config_use_large_screen_shade_header)).thenReturn(false);
         mNotificationPanelViewController.updateResources();
-        verify(mLargeScreenShadeHeaderController).setActive(false);
+        verify(mLargeScreenShadeHeaderController).setLargeScreenActive(false);
     }
 
     @Test
@@ -1177,14 +1211,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
@@ -1192,7 +1226,7 @@
         when(mPowerManager.isPowerSaveMode()).thenReturn(false);
         when(mAmbientState.getDozeAmount()).thenReturn(0.5f);
         mNotificationPanelViewController.startUnlockHintAnimation();
-        assertThat(mNotificationPanelViewController.mHintAnimationRunning).isFalse();
+        assertThat(mNotificationPanelViewController.isHintAnimationRunning()).isFalse();
     }
 
     @Test
@@ -1250,6 +1284,29 @@
     }
 
     @Test
+    public void testPanelClosedWhenClosingQsInSplitShade() {
+        mPanelExpansionStateManager.onPanelExpansionChanged(/* fraction= */ 1,
+                /* expanded= */ true, /* tracking= */ false, /* dragDownPxAmount= */ 0);
+        enableSplitShade(/* enabled= */ true);
+        mNotificationPanelViewController.setExpandedFraction(1f);
+
+        assertThat(mNotificationPanelViewController.isClosing()).isFalse();
+        mNotificationPanelViewController.animateCloseQs(false);
+        assertThat(mNotificationPanelViewController.isClosing()).isTrue();
+    }
+
+    @Test
+    public void testPanelStaysOpenWhenClosingQs() {
+        mPanelExpansionStateManager.onPanelExpansionChanged(/* fraction= */ 1,
+                /* expanded= */ true, /* tracking= */ false, /* dragDownPxAmount= */ 0);
+        mNotificationPanelViewController.setExpandedFraction(1f);
+
+        assertThat(mNotificationPanelViewController.isClosing()).isFalse();
+        mNotificationPanelViewController.animateCloseQs(false);
+        assertThat(mNotificationPanelViewController.isClosing()).isFalse();
+    }
+
+    @Test
     public void interceptTouchEvent_withinQs_shadeExpanded_startsQsTracking() {
         mNotificationPanelViewController.mQs = mQs;
         when(mQsFrame.getX()).thenReturn(0f);
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/shared/regionsampling/RegionSamplingInstanceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/regionsampling/RegionSamplingInstanceTest.kt
new file mode 100644
index 0000000..09d51f6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/regionsampling/RegionSamplingInstanceTest.kt
@@ -0,0 +1,113 @@
+package com.android.systemui.shared.regionsampling
+
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.shared.navigationbar.RegionSamplingHelper
+import java.io.PrintWriter
+import java.util.concurrent.Executor
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.junit.MockitoJUnit
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class RegionSamplingInstanceTest : SysuiTestCase() {
+
+    @JvmField @Rule
+    val mockito = MockitoJUnit.rule()
+
+    @Mock private lateinit var sampledView: View
+    @Mock private lateinit var mainExecutor: Executor
+    @Mock private lateinit var bgExecutor: Executor
+    @Mock private lateinit var regionSampler: RegionSamplingHelper
+    @Mock private lateinit var updateFun: RegionSamplingInstance.UpdateColorCallback
+    @Mock private lateinit var pw: PrintWriter
+    @Mock private lateinit var callback: RegionSamplingHelper.SamplingCallback
+
+    private lateinit var regionSamplingInstance: RegionSamplingInstance
+
+    @Before
+    fun setUp() {
+        whenever(sampledView.isAttachedToWindow).thenReturn(true)
+        whenever(regionSampler.callback).thenReturn(this@RegionSamplingInstanceTest.callback)
+
+        regionSamplingInstance = object : RegionSamplingInstance(
+                sampledView,
+                mainExecutor,
+                bgExecutor,
+                true,
+                updateFun
+        ) {
+            override fun createRegionSamplingHelper(
+                    sampledView: View,
+                    callback: RegionSamplingHelper.SamplingCallback,
+                    mainExecutor: Executor?,
+                    bgExecutor: Executor?
+            ): RegionSamplingHelper {
+                return this@RegionSamplingInstanceTest.regionSampler
+            }
+        }
+    }
+
+    @Test
+    fun testStartRegionSampler() {
+        regionSamplingInstance.startRegionSampler()
+
+        verify(regionSampler).start(Rect(0, 0, 0, 0))
+    }
+
+    @Test
+    fun testStopRegionSampler() {
+        regionSamplingInstance.stopRegionSampler()
+
+        verify(regionSampler).stop()
+    }
+
+    @Test
+    fun testDump() {
+        regionSamplingInstance.dump(pw)
+
+        verify(regionSampler).dump(pw)
+    }
+
+    @Test
+    fun testUpdateColorCallback() {
+        regionSampler.callback.onRegionDarknessChanged(false)
+        verify(regionSampler.callback).onRegionDarknessChanged(false)
+        clearInvocations(regionSampler.callback)
+        regionSampler.callback.onRegionDarknessChanged(true)
+        verify(regionSampler.callback).onRegionDarknessChanged(true)
+    }
+
+    @Test
+    fun testFlagFalse() {
+        regionSamplingInstance = object : RegionSamplingInstance(
+                sampledView,
+                mainExecutor,
+                bgExecutor,
+                false,
+                updateFun
+        ) {
+            override fun createRegionSamplingHelper(
+                    sampledView: View,
+                    callback: RegionSamplingHelper.SamplingCallback,
+                    mainExecutor: Executor?,
+                    bgExecutor: Executor?
+            ): RegionSamplingHelper {
+                return this@RegionSamplingInstanceTest.regionSampler
+            }
+        }
+
+        Assert.assertEquals(regionSamplingInstance.regionSampler, null)
+    }
+}
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/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
index 7687d12..dd2b667 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -29,7 +29,9 @@
 import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.clearInvocations;
 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;
@@ -59,6 +61,7 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager.KeyguardNotificationSuppressor;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager.NotificationStateChangedListener;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
@@ -325,6 +328,38 @@
     }
 
     @Test
+    public void testUpdateIsPublicMode() {
+        when(mKeyguardStateController.isMethodSecure()).thenReturn(true);
+
+        NotificationStateChangedListener listener = mock(NotificationStateChangedListener.class);
+        mLockscreenUserManager.addNotificationStateChangedListener(listener);
+        mLockscreenUserManager.mCurrentProfiles.append(0, mock(UserInfo.class));
+
+        // first call explicitly sets user 0 to not public; notifies
+        mLockscreenUserManager.updatePublicMode();
+        assertFalse(mLockscreenUserManager.isLockscreenPublicMode(0));
+        verify(listener).onNotificationStateChanged();
+        clearInvocations(listener);
+
+        // calling again has no changes; does not notify
+        mLockscreenUserManager.updatePublicMode();
+        assertFalse(mLockscreenUserManager.isLockscreenPublicMode(0));
+        verify(listener, never()).onNotificationStateChanged();
+
+        // Calling again with keyguard now showing makes user 0 public; notifies
+        when(mKeyguardStateController.isShowing()).thenReturn(true);
+        mLockscreenUserManager.updatePublicMode();
+        assertTrue(mLockscreenUserManager.isLockscreenPublicMode(0));
+        verify(listener).onNotificationStateChanged();
+        clearInvocations(listener);
+
+        // calling again has no changes; does not notify
+        mLockscreenUserManager.updatePublicMode();
+        assertTrue(mLockscreenUserManager.isLockscreenPublicMode(0));
+        verify(listener, never()).onNotificationStateChanged();
+    }
+
+    @Test
     public void testShowSilentNotifications_settingSaysShow() {
         mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1);
         mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1);
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/connectivity/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerBaseTest.java
index 0d1879c..f8a0d2f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerBaseTest.java
@@ -70,8 +70,6 @@
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.demomode.DemoModeController;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.log.LogBuffer;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
@@ -127,8 +125,8 @@
     protected CarrierConfigTracker mCarrierConfigTracker;
     protected FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
     protected Handler mMainHandler;
-    protected FeatureFlags mFeatureFlags;
     protected WifiStatusTrackerFactory mWifiStatusTrackerFactory;
+    protected MobileSignalControllerFactory mMobileFactory;
 
     protected int mSubId;
 
@@ -158,9 +156,6 @@
 
     @Before
     public void setUp() throws Exception {
-        mFeatureFlags = mock(FeatureFlags.class);
-        when(mFeatureFlags.isEnabled(Flags.COMBINED_STATUS_BAR_SIGNAL_ICONS)).thenReturn(false);
-
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
         Settings.Global.putInt(mContext.getContentResolver(), Global.AIRPLANE_MODE_ON, 0);
         TestableResources res = mContext.getOrCreateTestableResources();
@@ -224,6 +219,11 @@
 
         mWifiStatusTrackerFactory = new WifiStatusTrackerFactory(
                 mContext, mMockWm, mMockNsm, mMockCm, mMainHandler);
+        mMobileFactory = new MobileSignalControllerFactory(
+                mContext,
+                mCallbackHandler,
+                mCarrierConfigTracker
+        );
 
         mNetworkController = new NetworkControllerImpl(mContext,
                 mMockCm,
@@ -243,8 +243,8 @@
                 mDemoModeController,
                 mCarrierConfigTracker,
                 mWifiStatusTrackerFactory,
+                mMobileFactory,
                 mMainHandler,
-                mFeatureFlags,
                 mock(DumpManager.class),
                 mock(LogBuffer.class)
         );
@@ -438,10 +438,6 @@
         updateSignalStrength();
     }
 
-    public void setImsType(int imsType) {
-        mMobileSignalController.setImsType(imsType);
-    }
-
     public void setIsGsm(boolean gsm) {
         when(mSignalStrength.isGsm()).thenReturn(gsm);
         updateSignalStrength();
@@ -637,5 +633,4 @@
     protected void assertDataNetworkNameEquals(String expected) {
         assertEquals("Data network name", expected, mNetworkController.getMobileDataNetworkName());
     }
-
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java
index e3dd6f4..ed8a3e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java
@@ -145,8 +145,8 @@
                 mDemoModeController,
                 mock(CarrierConfigTracker.class),
                 mWifiStatusTrackerFactory,
+                mMobileFactory,
                 new Handler(TestableLooper.get(this).getLooper()),
-                mFeatureFlags,
                 mock(DumpManager.class),
                 mock(LogBuffer.class));
         setupNetworkController();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
index 698899a..a76676e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
@@ -85,8 +85,8 @@
                 mDemoModeController,
                 mCarrierConfigTracker,
                 mWifiStatusTrackerFactory,
+                mMobileFactory,
                 mMainHandler,
-                mFeatureFlags,
                 mock(DumpManager.class),
                 mock(LogBuffer.class)
         );
@@ -121,8 +121,8 @@
                 mDemoModeController,
                 mCarrierConfigTracker,
                 mWifiStatusTrackerFactory,
+                mMobileFactory,
                 mMainHandler,
-                mFeatureFlags,
                 mock(DumpManager.class),
                 mock(LogBuffer.class));
         TestableLooper.get(this).processAllMessages();
@@ -155,8 +155,8 @@
                 mDemoModeController,
                 mock(CarrierConfigTracker.class),
                 mWifiStatusTrackerFactory,
+                mMobileFactory,
                 mMainHandler,
-                mFeatureFlags,
                 mock(DumpManager.class),
                 mock(LogBuffer.class));
         setupNetworkController();
@@ -192,8 +192,8 @@
                 mDemoModeController,
                 mock(CarrierConfigTracker.class),
                 mWifiStatusTrackerFactory,
+                mMobileFactory,
                 mMainHandler,
-                mFeatureFlags,
                 mock(DumpManager.class),
                 mock(LogBuffer.class));
         mNetworkController.registerListeners();
@@ -277,8 +277,8 @@
                 mDemoModeController,
                 mock(CarrierConfigTracker.class),
                 mWifiStatusTrackerFactory,
+                mMobileFactory,
                 mMainHandler,
-                mFeatureFlags,
                 mock(DumpManager.class),
                 mock(LogBuffer.class));
         setupNetworkController();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java
index 3f71491..68170ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java
@@ -30,7 +30,6 @@
 import android.net.vcn.VcnTransportInfo;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
-import android.telephony.CellSignalStrength;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 
@@ -285,44 +284,6 @@
         verifyLastMobileDataIndicatorsForVcn(false, 1, 0, false);
     }
 
-    @Test
-    public void testCallStrengh() {
-        if (true) return;
-        String testSsid = "Test SSID";
-        setWifiEnabled(true);
-        setWifiState(true, testSsid);
-        // Set the ImsType to be IMS_TYPE_WLAN
-        setImsType(2);
-        setWifiLevel(1);
-        for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
-            setWifiLevel(testLevel);
-            verifyLastCallStrength(TelephonyIcons.WIFI_CALL_STRENGTH_ICONS[testLevel]);
-        }
-        // Set the ImsType to be IMS_TYPE_WWAN
-        setImsType(1);
-        setupDefaultSignal();
-        for (int testStrength = 0;
-                testStrength < CellSignalStrength.getNumSignalStrengthLevels(); testStrength++) {
-            setLevel(testStrength);
-            verifyLastCallStrength(TelephonyIcons.MOBILE_CALL_STRENGTH_ICONS[testStrength]);
-        }
-    }
-
-    @Test
-    public void testNonPrimaryWiFi() {
-        if (true) return;
-        String testSsid = "Test SSID";
-        setWifiEnabled(true);
-        setWifiState(true, testSsid);
-        // Set the ImsType to be IMS_TYPE_WLAN
-        setImsType(2);
-        setWifiLevel(1);
-        verifyLastCallStrength(TelephonyIcons.WIFI_CALL_STRENGTH_ICONS[1]);
-        when(mWifiInfo.isPrimary()).thenReturn(false);
-        setWifiLevel(3);
-        verifyLastCallStrength(TelephonyIcons.WIFI_CALL_STRENGTH_ICONS[1]);
-    }
-
     protected void setWifiActivity(int activity) {
         // TODO: Not this, because this variable probably isn't sticking around.
         mNetworkController.mWifiSignalController.setActivity(activity);
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 54cbe24..5386171 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,13 +25,16 @@
 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.android.systemui.statusbar.StatusBarState.SHADE_LOCKED;
 
 import static com.google.common.truth.Truth.assertThat;
 
 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;
@@ -59,6 +62,7 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -85,6 +89,8 @@
     @Mock
     StatusBarStateController mStatusBarStateController;
     @Mock
+    KeyguardStateController mKeyguardStateController;
+    @Mock
     HeadsUpManager mHeadsUpManager;
     @Mock
     NotificationInterruptLogger mLogger;
@@ -96,12 +102,15 @@
     NotifPipelineFlags mFlags;
     @Mock
     KeyguardNotificationVisibilityProvider mKeyguardNotificationVisibilityProvider;
+    @Mock
+    PendingIntent mPendingIntent;
 
     private NotificationInterruptStateProviderImpl mNotifInterruptionStateProvider;
 
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
+        when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(false);
 
         mNotifInterruptionStateProvider =
                 new NotificationInterruptStateProviderImpl(
@@ -112,6 +121,7 @@
                         mNotificationFilter,
                         mBatteryController,
                         mStatusBarStateController,
+                        mKeyguardStateController,
                         mHeadsUpManager,
                         mLogger,
                         mMockHandler,
@@ -197,7 +207,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
@@ -207,7 +217,7 @@
     @Test
     public void testDoNotRunFilterOnNewPipeline() {
         // WHEN this entry should be filtered out
-        NotificationEntry entry  = createNotification(IMPORTANCE_DEFAULT);
+        NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
         mNotifInterruptionStateProvider.shouldHeadsUp(entry);
         verify(mNotificationFilter, times(0)).shouldFilterOut(eq(entry));
     }
@@ -422,6 +432,224 @@
         assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
     }
 
+    @Test
+    public void testShouldNotFullScreen_notPendingIntent_withStrictFlag() throws Exception {
+        when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
+        testShouldNotFullScreen_notPendingIntent();
+    }
+
+    @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_withStrictFlag() throws Exception {
+        when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
+        testShouldNotFullScreen_notHighImportance();
+    }
+
+    @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_withStrictFlag() throws Exception {
+        when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
+        testShouldNotFullScreen_isGroupAlertSilenced();
+    }
+
+    @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_withStrictFlag() throws Exception {
+        when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
+        testShouldFullScreen_notInteractive();
+    }
+
+    @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_withStrictFlag() throws Exception {
+        when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
+        testShouldFullScreen_isDreaming();
+    }
+
+    @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_withStrictFlag() throws Exception {
+        when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
+        testShouldFullScreen_onKeyguard();
+    }
+
+    @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_withStrictFlag() throws Exception {
+        when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
+        testShouldNotFullScreen_willHun();
+    }
+
+    @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");
+    }
+
+    @Test
+    public void testShouldFullScreen_snoozed_occluding_withStrictRules() throws Exception {
+        when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
+        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);
+        when(mKeyguardStateController.isShowing()).thenReturn(true);
+        when(mKeyguardStateController.isOccluded()).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 while keyguard occluded");
+    }
+
+    @Test
+    public void testShouldFullScreen_snoozed_lockedShade_withStrictRules() throws Exception {
+        when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
+        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_LOCKED);
+        when(mHeadsUpManager.isSnoozed("a")).thenReturn(true);
+        when(mKeyguardStateController.isShowing()).thenReturn(true);
+        when(mKeyguardStateController.isOccluded()).thenReturn(false);
+
+        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, "Keyguard is showing and not occluded");
+    }
+
+    @Test
+    public void testShouldNotFullScreen_snoozed_unlocked_withStrictRules() throws Exception {
+        when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
+        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);
+        when(mKeyguardStateController.isShowing()).thenReturn(false);
+        when(mKeyguardStateController.isOccluded()).thenReturn(false);
+
+        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
+                .isFalse();
+        verify(mLogger).logNoHeadsUpPackageSnoozed(entry);
+        verify(mLogger, never()).logNoFullscreen(any(), any());
+        verify(mLogger).logNoFullscreenWarning(entry, "Expected not to HUN while not on keyguard");
+        verify(mLogger, never()).logFullscreen(any(), any());
+    }
+
     /**
      * Bubbles can happen.
      */
@@ -516,8 +744,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 +777,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 +791,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/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/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 371119c..4ccbc6d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -490,7 +490,7 @@
         mAutoTileManager.init();
         when(mAutoAddTracker.isAdded(TEST_CUSTOM_SAFETY_SPEC)).thenReturn(true);
         mAutoTileManager.mSafetyCallback.onSafetyCenterEnableChanged(false);
-        verify(mQsTileHost, times(1)).removeTile(safetyComponent);
+        verify(mQsTileHost, times(1)).removeTile(TEST_CUSTOM_SAFETY_SPEC);
     }
 
     @Test
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..7b7a48b 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
@@ -22,24 +22,28 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.StatusBarManager;
 import android.os.PowerManager;
 import android.os.Vibrator;
 import android.testing.AndroidTestingRunner;
+import android.view.InsetsVisibilities;
 
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.testing.FakeMetricsLogger;
+import com.android.internal.statusbar.LetterboxDetails;
+import com.android.internal.view.AppearanceRegion;
 import com.android.keyguard.KeyguardUpdateMonitor;
 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.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DisableFlagsLogger;
-import com.android.systemui.statusbar.StatusBarStateControllerImpl;
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -58,6 +62,7 @@
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase {
+
     @Mock private CentralSurfaces mCentralSurfaces;
     @Mock private ShadeController mShadeController;
     @Mock private CommandQueue mCommandQueue;
@@ -72,14 +77,12 @@
     @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     @Mock private AssistManager mAssistManager;
     @Mock private DozeServiceHost mDozeServiceHost;
-    @Mock private StatusBarStateControllerImpl mStatusBarStateController;
-    @Mock private NotificationShadeWindowView mNotificationShadeWindowView;
     @Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
     @Mock private PowerManager mPowerManager;
     @Mock private VibratorHelper mVibratorHelper;
     @Mock private Vibrator mVibrator;
-    @Mock private LightBarController mLightBarController;
     @Mock private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
+    @Mock private SystemBarAttributesListener mSystemBarAttributesListener;
 
     CentralSurfacesCommandQueueCallbacks mSbcqCallbacks;
 
@@ -104,16 +107,14 @@
                 mStatusBarKeyguardViewManager,
                 mAssistManager,
                 mDozeServiceHost,
-                mStatusBarStateController,
-                mNotificationShadeWindowView,
                 mNotificationStackScrollLayoutController,
                 mStatusBarHideIconsForBouncerManager,
                 mPowerManager,
                 mVibratorHelper,
                 Optional.of(mVibrator),
-                mLightBarController,
                 new DisableFlagsLogger(),
-                DEFAULT_DISPLAY);
+                DEFAULT_DISPLAY,
+                mSystemBarAttributesListener);
 
         when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
         when(mRemoteInputQuickSettingsDisabler.adjustDisableFlags(anyInt()))
@@ -168,5 +169,59 @@
         verify(mDozeServiceHost).setAlwaysOnSuppressed(false);
     }
 
+    @Test
+    public void onSystemBarAttributesChanged_forwardsToSysBarAttrsListener() {
+        int displayId = DEFAULT_DISPLAY;
+        int appearance = 123;
+        AppearanceRegion[] appearanceRegions = new AppearanceRegion[]{};
+        boolean navbarColorManagedByIme = true;
+        int behavior = 456;
+        InsetsVisibilities requestedVisibilities = new InsetsVisibilities();
+        String packageName = "test package name";
+        LetterboxDetails[] letterboxDetails = new LetterboxDetails[]{};
 
+        mSbcqCallbacks.onSystemBarAttributesChanged(
+                displayId,
+                appearance,
+                appearanceRegions,
+                navbarColorManagedByIme,
+                behavior,
+                requestedVisibilities,
+                packageName,
+                letterboxDetails);
+
+        verify(mSystemBarAttributesListener).onSystemBarAttributesChanged(
+                displayId,
+                appearance,
+                appearanceRegions,
+                navbarColorManagedByIme,
+                behavior,
+                requestedVisibilities,
+                packageName,
+                letterboxDetails
+        );
+    }
+
+    @Test
+    public void onSystemBarAttributesChanged_differentDisplayId_doesNotForwardToAttrsListener() {
+        int appearance = 123;
+        AppearanceRegion[] appearanceRegions = new AppearanceRegion[]{};
+        boolean navbarColorManagedByIme = true;
+        int behavior = 456;
+        InsetsVisibilities requestedVisibilities = new InsetsVisibilities();
+        String packageName = "test package name";
+        LetterboxDetails[] letterboxDetails = new LetterboxDetails[]{};
+
+        mSbcqCallbacks.onSystemBarAttributesChanged(
+                DEFAULT_DISPLAY + 1,
+                appearance,
+                appearanceRegions,
+                navbarColorManagedByIme,
+                behavior,
+                requestedVisibilities,
+                packageName,
+                letterboxDetails);
+
+        verifyZeroInteractions(mSystemBarAttributesListener);
+    }
 }
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 b4532c4..c6fb0ce 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();
@@ -308,8 +306,13 @@
         mNotificationInterruptStateProvider =
                 new TestableNotificationInterruptStateProviderImpl(mContext.getContentResolver(),
                         mPowerManager,
-                        mDreamManager, mAmbientDisplayConfiguration, mNotificationFilter,
-                        mStatusBarStateController, mBatteryController, mHeadsUpManager,
+                        mDreamManager,
+                        mAmbientDisplayConfiguration,
+                        mNotificationFilter,
+                        mStatusBarStateController,
+                        mKeyguardStateController,
+                        mBatteryController,
+                        mHeadsUpManager,
                         mock(NotificationInterruptLogger.class),
                         new Handler(TestableLooper.get(this).getLooper()),
                         mock(NotifPipelineFlags.class),
@@ -401,7 +404,6 @@
                 new FalsingManagerFake(),
                 new FalsingCollectorFake(),
                 mBroadcastDispatcher,
-                mNotifShadeEventSource,
                 mNotificationEntryManager,
                 mNotificationGutsManager,
                 notificationLogger,
@@ -416,13 +418,11 @@
                 mLockscreenUserManager,
                 mRemoteInputManager,
                 mUserSwitcherController,
-                mNetworkController,
                 mBatteryController,
                 mColorExtractor,
                 new ScreenLifecycle(mDumpManager),
                 wakefulnessLifecycle,
                 mStatusBarStateController,
-                Optional.of(mBubblesManager),
                 Optional.of(mBubbles),
                 mVisualStabilityManager,
                 mDeviceProvisionedController,
@@ -434,7 +434,6 @@
                 mDozeParameters,
                 mScrimController,
                 mLockscreenWallpaperLazy,
-                mLockscreenGestureLogger,
                 mBiometricUnlockControllerLazy,
                 mDozeServiceHost,
                 mPowerManager, mScreenPinningRequest,
@@ -466,7 +465,6 @@
                 mLockscreenTransitionController,
                 mFeatureFlags,
                 mKeyguardUnlockAnimationController,
-                new Handler(TestableLooper.get(this).getLooper()),
                 mMainExecutor,
                 new MessageRouterImpl(mMainExecutor),
                 mWallpaperManager,
@@ -475,7 +473,6 @@
                 mNotifPipelineFlags,
                 mJankMonitor,
                 mDeviceStateManager,
-                mDreamOverlayStateController,
                 mWiredChargingRippleController, mDreamManager);
         when(mKeyguardViewMediator.registerCentralSurfaces(
                 any(CentralSurfacesImpl.class),
@@ -999,6 +996,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);
@@ -1028,15 +1041,28 @@
                 AmbientDisplayConfiguration ambientDisplayConfiguration,
                 NotificationFilter filter,
                 StatusBarStateController controller,
+                KeyguardStateController keyguardStateController,
                 BatteryController batteryController,
                 HeadsUpManager headsUpManager,
                 NotificationInterruptLogger logger,
                 Handler mainHandler,
                 NotifPipelineFlags flags,
                 KeyguardNotificationVisibilityProvider keyguardNotificationVisibilityProvider) {
-            super(contentResolver, powerManager, dreamManager, ambientDisplayConfiguration, filter,
-                    batteryController, controller, headsUpManager, logger, mainHandler,
-                    flags, keyguardNotificationVisibilityProvider);
+            super(
+                    contentResolver,
+                    powerManager,
+                    dreamManager,
+                    ambientDisplayConfiguration,
+                    filter,
+                    batteryController,
+                    controller,
+                    keyguardStateController,
+                    headsUpManager,
+                    logger,
+                    mainHandler,
+                    flags,
+                    keyguardNotificationVisibilityProvider
+            );
             mUseHeadsUp = true;
         }
     }
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/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/LetterboxAppearanceCalculatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
new file mode 100644
index 0000000..0531bc7
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
@@ -0,0 +1,205 @@
+/*
+ * 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 android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import android.view.WindowInsetsController
+import android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS
+import androidx.test.filters.SmallTest
+import com.android.internal.statusbar.LetterboxDetails
+import com.android.internal.view.AppearanceRegion
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent
+import com.google.common.truth.Expect
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class LetterboxAppearanceCalculatorTest : SysuiTestCase() {
+
+    companion object {
+        private const val DEFAULT_APPEARANCE = 0
+        private const val TEST_APPEARANCE = WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
+        private val TEST_APPEARANCE_REGION_BOUNDS = Rect(0, 0, 20, 100)
+        private val TEST_APPEARANCE_REGION =
+            AppearanceRegion(TEST_APPEARANCE, TEST_APPEARANCE_REGION_BOUNDS)
+        private val TEST_APPEARANCE_REGIONS = arrayOf(TEST_APPEARANCE_REGION)
+        private val TEST_WINDOW_BOUNDS = Rect(0, 0, 500, 500)
+    }
+
+    @get:Rule var expect = Expect.create()
+
+    @Mock private lateinit var lightBarController: LightBarController
+    @Mock private lateinit var statusBarBoundsProvider: StatusBarBoundsProvider
+    @Mock private lateinit var statusBarFragmentComponent: StatusBarFragmentComponent
+    @Mock private lateinit var dumpManager: DumpManager
+
+    private lateinit var calculator: LetterboxAppearanceCalculator
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        whenever(statusBarFragmentComponent.boundsProvider).thenReturn(statusBarBoundsProvider)
+        calculator = LetterboxAppearanceCalculator(lightBarController, dumpManager)
+        calculator.onStatusBarViewInitialized(statusBarFragmentComponent)
+    }
+
+    @Test
+    fun getLetterboxAppearance_overlapStartSide_returnsOriginalWithScrim() {
+        whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 100, 100))
+        whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(200, 0, 300, 100))
+        val letterbox = letterboxWithInnerBounds(Rect(50, 50, 150, 150))
+
+        val letterboxAppearance =
+            calculator.getLetterboxAppearance(
+                TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf(letterbox))
+
+        expect
+            .that(letterboxAppearance.appearance)
+            .isEqualTo(TEST_APPEARANCE or APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS)
+        expect.that(letterboxAppearance.appearanceRegions).isEqualTo(TEST_APPEARANCE_REGIONS)
+    }
+
+    @Test
+    fun getLetterboxAppearance_overlapEndSide_returnsOriginalWithScrim() {
+        whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 100, 100))
+        whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(200, 0, 300, 100))
+        val letterbox = letterboxWithInnerBounds(Rect(150, 50, 250, 150))
+
+        val letterboxAppearance =
+            calculator.getLetterboxAppearance(
+                TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf(letterbox))
+
+        expect
+            .that(letterboxAppearance.appearance)
+            .isEqualTo(TEST_APPEARANCE or APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS)
+        expect.that(letterboxAppearance.appearanceRegions).isEqualTo(TEST_APPEARANCE_REGIONS)
+    }
+
+    @Test
+    fun getLetterboxAppearance_noOverlap_returnsAppearanceWithoutScrim() {
+        whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 100, 100))
+        whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(200, 0, 300, 100))
+        val letterbox = letterboxWithInnerBounds(Rect(101, 0, 199, 100))
+
+        val letterboxAppearance =
+            calculator.getLetterboxAppearance(
+                TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf(letterbox))
+
+        assertThat(letterboxAppearance.appearance).isEqualTo(TEST_APPEARANCE)
+    }
+
+    @Test
+    fun getLetterboxAppearance_letterboxContainsStartSide_returnsAppearanceWithoutScrim() {
+        whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 100, 100))
+        whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(200, 0, 300, 100))
+        val letterbox = letterboxWithInnerBounds(Rect(0, 0, 101, 101))
+
+        val letterboxAppearance =
+            calculator.getLetterboxAppearance(
+                TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf(letterbox))
+
+        assertThat(letterboxAppearance.appearance).isEqualTo(TEST_APPEARANCE)
+    }
+
+    @Test
+    fun getLetterboxAppearance_letterboxContainsEndSide_returnsAppearanceWithoutScrim() {
+        whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 100, 100))
+        whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(200, 0, 300, 100))
+        val letterbox = letterboxWithInnerBounds(Rect(199, 0, 301, 101))
+
+        val letterboxAppearance =
+            calculator.getLetterboxAppearance(
+                TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf(letterbox))
+
+        assertThat(letterboxAppearance.appearance).isEqualTo(TEST_APPEARANCE)
+    }
+
+    @Test
+    fun getLetterboxAppearance_letterboxContainsEntireStatusBar_returnsAppearanceWithoutScrim() {
+        whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 100, 100))
+        whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(200, 0, 300, 100))
+        val letterbox = letterboxWithInnerBounds(Rect(0, 0, 300, 100))
+
+        val letterboxAppearance =
+            calculator.getLetterboxAppearance(
+                TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf(letterbox))
+
+        assertThat(letterboxAppearance.appearance).isEqualTo(TEST_APPEARANCE)
+    }
+
+    @Test
+    fun getLetterboxAppearance_returnsAdaptedAppearanceRegions_basedOnLetterboxInnerBounds() {
+        whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 0, 0))
+        whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(0, 0, 0, 0))
+        val letterbox = letterboxWithInnerBounds(Rect(150, 0, 300, 800))
+        val letterboxRegion = TEST_APPEARANCE_REGION.copy(bounds = letterbox.letterboxFullBounds)
+
+        val letterboxAppearance =
+            calculator.getLetterboxAppearance(
+                TEST_APPEARANCE, arrayOf(letterboxRegion), arrayOf(letterbox))
+
+        val letterboxAdaptedRegion = letterboxRegion.copy(bounds = letterbox.letterboxInnerBounds)
+        assertThat(letterboxAppearance.appearanceRegions.toList()).contains(letterboxAdaptedRegion)
+        assertThat(letterboxAppearance.appearanceRegions.toList()).doesNotContain(letterboxRegion)
+    }
+
+    @Test
+    fun getLetterboxAppearance_returnsDefaultAppearanceRegions_basedOnLetterboxOuterBounds() {
+        whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 0, 0))
+        whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(0, 0, 0, 0))
+        val letterbox =
+            letterboxWithBounds(
+                innerBounds = Rect(left = 25, top = 0, right = 75, bottom = 100),
+                fullBounds = Rect(left = 0, top = 0, right = 100, bottom = 100))
+        val letterboxRegion = TEST_APPEARANCE_REGION.copy(bounds = letterbox.letterboxFullBounds)
+
+        val letterboxAppearance =
+            calculator.getLetterboxAppearance(
+                TEST_APPEARANCE, arrayOf(letterboxRegion), arrayOf(letterbox))
+
+        val outerRegions =
+            listOf(
+                AppearanceRegion(
+                    DEFAULT_APPEARANCE, Rect(left = 0, top = 0, right = 25, bottom = 100)),
+                AppearanceRegion(
+                    DEFAULT_APPEARANCE, Rect(left = 75, top = 0, right = 100, bottom = 100)),
+            )
+        assertThat(letterboxAppearance.appearanceRegions.toList())
+            .containsAtLeastElementsIn(outerRegions)
+    }
+
+    private fun letterboxWithBounds(innerBounds: Rect, fullBounds: Rect) =
+        LetterboxDetails(innerBounds, fullBounds, TEST_APPEARANCE)
+
+    private fun letterboxWithInnerBounds(innerBounds: Rect) =
+        letterboxWithBounds(innerBounds, fullBounds = TEST_WINDOW_BOUNDS)
+}
+
+private fun AppearanceRegion.copy(appearance: Int = this.appearance, bounds: Rect = this.bounds) =
+    AppearanceRegion(appearance, bounds)
+
+private fun Rect(left: Int, top: Int, right: Int, bottom: Int) = Rect(left, top, right, bottom)
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/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
index ba29e95..9892448 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
@@ -26,6 +26,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.shade.PanelViewController
 import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherController
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.unfold.SysUIUnfoldComponent
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
index 8d686ae..d6c995b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
@@ -20,6 +20,7 @@
 import android.view.ViewGroup
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.shade.PanelViewController
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
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/StatusBarBoundsProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarBoundsProviderTest.kt
new file mode 100644
index 0000000..d84010d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarBoundsProviderTest.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.systemui.statusbar.phone
+
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import android.view.View
+import android.widget.FrameLayout
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.phone.StatusBarBoundsProvider.BoundsChangeListener
+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.any
+import org.mockito.Mockito.doAnswer
+import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class StatusBarBoundsProviderTest : SysuiTestCase() {
+
+    companion object {
+        private val START_SIDE_BOUNDS = Rect(50, 100, 150, 200)
+        private val END_SIDE_BOUNDS = Rect(250, 300, 350, 400)
+    }
+
+    @Mock private lateinit var boundsChangeListener: BoundsChangeListener
+
+    private lateinit var boundsProvider: StatusBarBoundsProvider
+
+    private lateinit var startSideContent: View
+    private lateinit var endSideContent: View
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        startSideContent = spy(FrameLayout(context)).apply { setBoundsOnScreen(START_SIDE_BOUNDS) }
+        endSideContent = spy(FrameLayout(context)).apply { setBoundsOnScreen(END_SIDE_BOUNDS) }
+
+        boundsProvider =
+            StatusBarBoundsProvider(setOf(boundsChangeListener), startSideContent, endSideContent)
+    }
+
+    @Test
+    fun visibleStartSideBounds_returnsBoundsFromStartSideContentView() {
+        assertThat(boundsProvider.visibleStartSideBounds).isEqualTo(START_SIDE_BOUNDS)
+    }
+
+    @Test
+    fun visibleEndSideBounds_returnsBoundsFromEndSideContentView() {
+        assertThat(boundsProvider.visibleEndSideBounds).isEqualTo(END_SIDE_BOUNDS)
+    }
+
+    @Test
+    fun startBoundsChange_afterStart_notifiesListener() {
+        boundsProvider.start()
+        val newBounds = Rect(START_SIDE_BOUNDS).apply { left += 1 }
+
+        startSideContent.setBoundsOnScreen(newBounds)
+
+        verify(boundsChangeListener).onStatusBarBoundsChanged()
+    }
+
+    @Test
+    fun startBoundsChange_beforeStart_doesNotNotifyListener() {
+        val newBounds = Rect(START_SIDE_BOUNDS).apply { left += 1 }
+
+        startSideContent.setBoundsOnScreen(newBounds)
+
+        verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
+    }
+
+    @Test
+    fun startBoundsChange_afterStop_doesNotNotifyListener() {
+        boundsProvider.start()
+        boundsProvider.stop()
+        val newBounds = Rect(START_SIDE_BOUNDS).apply { left += 1 }
+
+        startSideContent.setBoundsOnScreen(newBounds)
+
+        verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
+    }
+
+    @Test
+    fun startLayoutChange_afterStart_boundsOnScreenSame_doesNotNotifyListener() {
+        boundsProvider.start()
+        val newBounds = Rect(START_SIDE_BOUNDS).apply { left += 1 }
+
+        startSideContent.layout(newBounds)
+
+        verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
+    }
+
+    @Test
+    fun endBoundsChange_afterStart_notifiesListener() {
+        boundsProvider.start()
+        val newBounds = Rect(START_SIDE_BOUNDS).apply { right += 1 }
+
+        endSideContent.setBoundsOnScreen(newBounds)
+
+        verify(boundsChangeListener).onStatusBarBoundsChanged()
+    }
+
+    @Test
+    fun endBoundsChange_beforeStart_doesNotNotifyListener() {
+        val newBounds = Rect(START_SIDE_BOUNDS).apply { right += 1 }
+
+        endSideContent.setBoundsOnScreen(newBounds)
+
+        verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
+    }
+
+    @Test
+    fun endBoundsChange_afterStop_doesNotNotifyListener() {
+        boundsProvider.start()
+        boundsProvider.stop()
+        val newBounds = Rect(START_SIDE_BOUNDS).apply { right += 1 }
+
+        endSideContent.setBoundsOnScreen(newBounds)
+
+        verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
+    }
+
+    @Test
+    fun endLayoutChange_afterStart_boundsOnScreenSame_doesNotNotifyListener() {
+        boundsProvider.start()
+        val newBounds = Rect(START_SIDE_BOUNDS).apply { right += 1 }
+
+        endSideContent.layout(newBounds)
+
+        verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
+    }
+}
+
+private fun View.setBoundsOnScreen(bounds: Rect) {
+    doAnswer { invocation ->
+            val boundsOutput = invocation.arguments[0] as Rect
+            boundsOutput.set(bounds)
+            return@doAnswer Unit
+        }
+        .`when`(this)
+        .getBoundsOnScreen(any())
+    layout(bounds.left, bounds.top, bounds.right, bounds.bottom)
+}
+
+private fun View.layout(rect: Rect) {
+    layout(rect.left, rect.top, rect.right, rect.bottom)
+}
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..4b7b650 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
@@ -16,12 +16,14 @@
 
 import static android.view.Display.DEFAULT_DISPLAY;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.Notification;
+import android.app.PendingIntent;
 import android.app.StatusBarManager;
 import android.metrics.LogMaker;
 import android.support.test.metricshelper.MetricsAsserts;
@@ -33,12 +35,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 +52,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 +62,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;
@@ -80,6 +81,8 @@
     private FakeMetricsLogger mMetricsLogger;
     private ShadeController mShadeController = mock(ShadeController.class);
     private CentralSurfaces mCentralSurfaces = mock(CentralSurfaces.class);
+    private KeyguardStateController mKeyguardStateController = mock(KeyguardStateController.class);
+    private NotifPipelineFlags mNotifPipelineFlags = mock(NotifPipelineFlags.class);
     private InitController mInitController = new InitController();
 
     @Before
@@ -114,7 +117,7 @@
                 mock(ScrimController.class),
                 mock(NotificationShadeWindowController.class),
                 mock(DynamicPrivacyController.class),
-                mock(KeyguardStateController.class),
+                mKeyguardStateController,
                 mock(KeyguardIndicationController.class),
                 mCentralSurfaces,
                 mock(ShadeControllerImpl.class),
@@ -123,16 +126,13 @@
                 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),
+                mNotifPipelineFlags,
                 mock(NotificationRemoteInputManager.Callback.class),
                 mock(NotificationListContainer.class));
         mInitController.executePostInitTasks();
@@ -143,6 +143,19 @@
     }
 
     @Test
+    public void testNoSuppressHeadsUp_default() {
+        Notification n = new Notification.Builder(getContext(), "a").build();
+        NotificationEntry entry = new NotificationEntryBuilder()
+                .setPkg("a")
+                .setOpPkg("a")
+                .setTag("a")
+                .setNotification(n)
+                .build();
+
+        assertFalse(mInterruptSuppressor.suppressAwakeHeadsUp(entry));
+    }
+
+    @Test
     public void testSuppressHeadsUp_disabledStatusBar() {
         Notification n = new Notification.Builder(getContext(), "a").build();
         NotificationEntry entry = new NotificationEntryBuilder()
@@ -178,6 +191,63 @@
     }
 
     @Test
+    public void testNoSuppressHeadsUp_FSI_occludedKeygaurd() {
+        when(mNotifPipelineFlags.fullScreenIntentRequiresKeyguard()).thenReturn(false);
+        Notification n = new Notification.Builder(getContext(), "a")
+                .setFullScreenIntent(mock(PendingIntent.class), true)
+                .build();
+        NotificationEntry entry = new NotificationEntryBuilder()
+                .setPkg("a")
+                .setOpPkg("a")
+                .setTag("a")
+                .setNotification(n)
+                .build();
+
+        when(mKeyguardStateController.isShowing()).thenReturn(true);
+        when(mKeyguardStateController.isOccluded()).thenReturn(true);
+        when(mCentralSurfaces.isOccluded()).thenReturn(true);
+        assertFalse(mInterruptSuppressor.suppressAwakeHeadsUp(entry));
+    }
+
+    @Test
+    public void testSuppressHeadsUp_FSI_nonOccludedKeygaurd() {
+        when(mNotifPipelineFlags.fullScreenIntentRequiresKeyguard()).thenReturn(false);
+        Notification n = new Notification.Builder(getContext(), "a")
+                .setFullScreenIntent(mock(PendingIntent.class), true)
+                .build();
+        NotificationEntry entry = new NotificationEntryBuilder()
+                .setPkg("a")
+                .setOpPkg("a")
+                .setTag("a")
+                .setNotification(n)
+                .build();
+
+        when(mKeyguardStateController.isShowing()).thenReturn(true);
+        when(mKeyguardStateController.isOccluded()).thenReturn(false);
+        when(mCentralSurfaces.isOccluded()).thenReturn(false);
+        assertTrue(mInterruptSuppressor.suppressAwakeHeadsUp(entry));
+    }
+
+    @Test
+    public void testNoSuppressHeadsUp_FSI_nonOccludedKeygaurd_withNewFlag() {
+        when(mNotifPipelineFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
+        Notification n = new Notification.Builder(getContext(), "a")
+                .setFullScreenIntent(mock(PendingIntent.class), true)
+                .build();
+        NotificationEntry entry = new NotificationEntryBuilder()
+                .setPkg("a")
+                .setOpPkg("a")
+                .setTag("a")
+                .setNotification(n)
+                .build();
+
+        when(mKeyguardStateController.isShowing()).thenReturn(true);
+        when(mKeyguardStateController.isOccluded()).thenReturn(false);
+        when(mCentralSurfaces.isOccluded()).thenReturn(false);
+        assertFalse(mInterruptSuppressor.suppressAwakeHeadsUp(entry));
+    }
+
+    @Test
     public void testSuppressInterruptions_vrMode() {
         Notification n = new Notification.Builder(getContext(), "a").build();
         NotificationEntry entry = new NotificationEntryBuilder()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemBarAttributesListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemBarAttributesListenerTest.kt
new file mode 100644
index 0000000..fa7b259
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemBarAttributesListenerTest.kt
@@ -0,0 +1,250 @@
+package com.android.systemui.statusbar.phone
+
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import android.view.Display
+import android.view.InsetsVisibilities
+import android.view.WindowInsetsController
+import android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
+import android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
+import android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS
+import android.view.WindowInsetsController.Appearance
+import androidx.test.filters.SmallTest
+import com.android.internal.statusbar.LetterboxDetails
+import com.android.internal.view.AppearanceRegion
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.SysuiStatusBarStateController
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mock
+import org.mockito.Mockito
+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
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class SystemBarAttributesListenerTest : SysuiTestCase() {
+
+    @Mock private lateinit var dumpManager: DumpManager
+    @Mock private lateinit var lightBarController: LightBarController
+    @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
+    @Mock private lateinit var letterboxAppearanceCalculator: LetterboxAppearanceCalculator
+    @Mock private lateinit var featureFlags: FeatureFlags
+    @Mock private lateinit var centralSurfaces: CentralSurfaces
+
+    private lateinit var sysBarAttrsListener: SystemBarAttributesListener
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        whenever(
+                letterboxAppearanceCalculator.getLetterboxAppearance(
+                    anyInt(), anyObject(), anyObject()))
+            .thenReturn(TEST_LETTERBOX_APPEARANCE)
+
+        sysBarAttrsListener =
+            SystemBarAttributesListener(
+                centralSurfaces,
+                featureFlags,
+                letterboxAppearanceCalculator,
+                statusBarStateController,
+                lightBarController,
+                dumpManager)
+    }
+
+    @Test
+    fun onSysBarAttrsChanged_forwardsAppearanceToCentralSurfaces() {
+        val appearance = APPEARANCE_LIGHT_STATUS_BARS or APPEARANCE_LIGHT_NAVIGATION_BARS
+
+        changeSysBarAttrs(appearance)
+
+        verify(centralSurfaces).setAppearance(appearance)
+    }
+
+    @Test
+    fun onSysBarAttrsChanged_flagTrue_forwardsLetterboxAppearanceToCentralSurfaces() {
+        whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true)
+
+        changeSysBarAttrs(TEST_APPEARANCE, TEST_LETTERBOX_DETAILS)
+
+        verify(centralSurfaces).setAppearance(TEST_LETTERBOX_APPEARANCE.appearance)
+    }
+
+    @Test
+    fun onSysBarAttrsChanged_flagTrue_noLetterbox_forwardsOriginalAppearanceToCtrlSrfcs() {
+        whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true)
+
+        changeSysBarAttrs(TEST_APPEARANCE, arrayOf<LetterboxDetails>())
+
+        verify(centralSurfaces).setAppearance(TEST_APPEARANCE)
+    }
+
+    @Test
+    fun onSysBarAttrsChanged_forwardsAppearanceToStatusBarStateController() {
+        changeSysBarAttrs(TEST_APPEARANCE)
+
+        verify(statusBarStateController)
+            .setSystemBarAttributes(eq(TEST_APPEARANCE), anyInt(), any(), any())
+    }
+
+    @Test
+    fun onSysBarAttrsChanged_flagTrue_forwardsLetterboxAppearanceToStatusBarStateCtrl() {
+        whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true)
+
+        changeSysBarAttrs(TEST_APPEARANCE, TEST_LETTERBOX_DETAILS)
+
+        verify(statusBarStateController)
+            .setSystemBarAttributes(
+                eq(TEST_LETTERBOX_APPEARANCE.appearance), anyInt(), any(), any())
+    }
+
+    @Test
+    fun onSysBarAttrsChanged_forwardsAppearanceToLightBarController() {
+        changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS)
+
+        verify(lightBarController)
+            .onStatusBarAppearanceChanged(
+                eq(TEST_APPEARANCE_REGIONS), anyBoolean(), anyInt(), anyBoolean())
+    }
+
+    @Test
+    fun onSysBarAttrsChanged_flagTrue_forwardsLetterboxAppearanceToLightBarController() {
+        whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true)
+
+        changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS)
+
+        verify(lightBarController)
+            .onStatusBarAppearanceChanged(
+                eq(TEST_LETTERBOX_APPEARANCE.appearanceRegions),
+                anyBoolean(),
+                anyInt(),
+                anyBoolean())
+    }
+
+    @Test
+    fun onStatusBarBoundsChanged_forwardsLetterboxAppearanceToStatusBarStateController() {
+        whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true)
+        changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS)
+        reset(centralSurfaces, lightBarController, statusBarStateController)
+
+        sysBarAttrsListener.onStatusBarBoundsChanged()
+
+        verify(statusBarStateController)
+            .setSystemBarAttributes(
+                eq(TEST_LETTERBOX_APPEARANCE.appearance), anyInt(), any(), any())
+    }
+
+    @Test
+    fun onStatusBarBoundsChanged_forwardsLetterboxAppearanceToLightBarController() {
+        whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true)
+        changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS)
+        reset(centralSurfaces, lightBarController, statusBarStateController)
+
+        sysBarAttrsListener.onStatusBarBoundsChanged()
+
+        verify(lightBarController)
+            .onStatusBarAppearanceChanged(
+                eq(TEST_LETTERBOX_APPEARANCE.appearanceRegions),
+                anyBoolean(),
+                anyInt(),
+                anyBoolean())
+    }
+
+    @Test
+    fun onStatusBarBoundsChanged_forwardsLetterboxAppearanceToCentralSurfaces() {
+        whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true)
+        changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS)
+        reset(centralSurfaces, lightBarController, statusBarStateController)
+
+        sysBarAttrsListener.onStatusBarBoundsChanged()
+
+        verify(centralSurfaces).setAppearance(TEST_LETTERBOX_APPEARANCE.appearance)
+    }
+
+    @Test
+    fun onStatusBarBoundsChanged_previousCallEmptyLetterbox_doesNothing() {
+        whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true)
+        changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf())
+        reset(centralSurfaces, lightBarController, statusBarStateController)
+
+        sysBarAttrsListener.onStatusBarBoundsChanged()
+
+        verifyZeroInteractions(centralSurfaces, lightBarController, statusBarStateController)
+    }
+
+    @Test
+    fun onStatusBarBoundsChanged_flagFalse_doesNothing() {
+        whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(false)
+        changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS)
+        reset(centralSurfaces, lightBarController, statusBarStateController)
+
+        sysBarAttrsListener.onStatusBarBoundsChanged()
+
+        verifyZeroInteractions(centralSurfaces, lightBarController, statusBarStateController)
+    }
+
+    private fun changeSysBarAttrs(@Appearance appearance: Int) {
+        changeSysBarAttrs(appearance, arrayOf<LetterboxDetails>())
+    }
+
+    private fun changeSysBarAttrs(
+        @Appearance appearance: Int,
+        letterboxDetails: Array<LetterboxDetails>
+    ) {
+        changeSysBarAttrs(appearance, arrayOf(), letterboxDetails)
+    }
+
+    private fun changeSysBarAttrs(
+        @Appearance appearance: Int,
+        appearanceRegions: Array<AppearanceRegion>
+    ) {
+        changeSysBarAttrs(appearance, appearanceRegions, arrayOf())
+    }
+
+    private fun changeSysBarAttrs(
+        @Appearance appearance: Int,
+        appearanceRegions: Array<AppearanceRegion>,
+        letterboxDetails: Array<LetterboxDetails>
+    ) {
+        sysBarAttrsListener.onSystemBarAttributesChanged(
+            Display.DEFAULT_DISPLAY,
+            appearance,
+            appearanceRegions,
+            /* navbarColorManagedByIme= */ false,
+            WindowInsetsController.BEHAVIOR_DEFAULT,
+            InsetsVisibilities(),
+            "package name",
+            letterboxDetails)
+    }
+
+    companion object {
+        private const val TEST_APPEARANCE =
+            APPEARANCE_LIGHT_STATUS_BARS or APPEARANCE_LIGHT_NAVIGATION_BARS
+        private val TEST_APPEARANCE_REGION = AppearanceRegion(TEST_APPEARANCE, Rect(0, 0, 150, 300))
+        private val TEST_APPEARANCE_REGIONS = arrayOf(TEST_APPEARANCE_REGION)
+        private val TEST_LETTERBOX_DETAILS =
+            arrayOf(
+                LetterboxDetails(
+                    /* letterboxInnerBounds= */ Rect(0, 0, 0, 0),
+                    /* letterboxFullBounds= */ Rect(0, 0, 0, 0),
+                    /* appAppearance= */ 0))
+        private val TEST_LETTERBOX_APPEARANCE =
+            LetterboxAppearance(/* appearance= */ APPEARANCE_LOW_PROFILE_BARS, arrayOf())
+    }
+}
+
+private fun <T> anyObject(): T {
+    return Mockito.anyObject<T>()
+}
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..1a8ffc1 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
@@ -41,17 +41,19 @@
 
 import com.android.systemui.R;
 import com.android.systemui.SysuiBaseFragmentTest;
+import com.android.systemui.dump.DumpManager;
 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;
@@ -104,6 +106,8 @@
     private NotificationPanelViewController mNotificationPanelViewController;
     @Mock
     private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
+    @Mock
+    private DumpManager mDumpManager;
 
     public CollapsedStatusBarFragmentTest() {
         super(CollapsedStatusBarFragment.class);
@@ -112,6 +116,7 @@
     @Before
     public void setup() {
         injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
+        mDependency.injectMockDependency(DarkIconDispatcher.class);
     }
 
     @Test
@@ -120,7 +125,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 +135,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 +234,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 +245,7 @@
 
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
-        assertEquals(View.VISIBLE, getSystemIconAreaView().getVisibility());
+        assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
         assertEquals(View.VISIBLE, getClockView().getVisibility());
     }
 
@@ -344,7 +349,8 @@
                         ),
                 mOperatorNameViewControllerFactory,
                 mSecureSettings,
-                mExecutor);
+                mExecutor,
+                mDumpManager);
     }
 
     private void setUpDaggerComponent() {
@@ -377,7 +383,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 1af8a77..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
@@ -54,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
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/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 2e58fc4..9866013 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,
@@ -315,6 +321,7 @@
                         mock(AmbientDisplayConfiguration.class),
                         mock(NotificationFilter.class),
                         mock(StatusBarStateController.class),
+                        mock(KeyguardStateController.class),
                         mock(BatteryController.class),
                         mock(HeadsUpManager.class),
                         mock(NotificationInterruptLogger.class),
@@ -325,6 +332,7 @@
         when(mShellTaskOrganizer.getExecutor()).thenReturn(syncExecutor);
         mBubbleController = new TestableBubbleController(
                 mContext,
+                mShellController,
                 mBubbleData,
                 mFloatingContentCoordinator,
                 mDataRepository,
@@ -353,7 +361,6 @@
                 mNotificationShadeWindowController,
                 mock(KeyguardStateController.class),
                 mShadeController,
-                mConfigurationController,
                 mStatusBarService,
                 mock(INotificationManager.class),
                 mVisibilityProvider,
@@ -375,6 +382,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/TestableNotificationInterruptStateProviderImpl.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java
index a7f0dc2..d80ea15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java
@@ -30,6 +30,7 @@
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 public class TestableNotificationInterruptStateProviderImpl
         extends NotificationInterruptStateProviderImpl {
@@ -41,6 +42,7 @@
             AmbientDisplayConfiguration ambientDisplayConfiguration,
             NotificationFilter filter,
             StatusBarStateController statusBarStateController,
+            KeyguardStateController keyguardStateController,
             BatteryController batteryController,
             HeadsUpManager headsUpManager,
             NotificationInterruptLogger logger,
@@ -54,6 +56,7 @@
                 filter,
                 batteryController,
                 statusBarStateController,
+                keyguardStateController,
                 headsUpManager,
                 logger,
                 mainHandler,
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..9c21366 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
@@ -24,27 +24,22 @@
 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;
 import com.android.systemui.statusbar.policy.UserInfoController;
 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,36 +60,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,
-                mProtoTracer, mWakefulnessLifecycle, mUserInfoController, mSysUiMainExecutor);
+        mWMShell = new WMShell(mContext, mShellInterface, Optional.of(mPip),
+                Optional.of(mSplitScreen), Optional.of(mOneHanded), mCommandQueue,
+                mConfigurationController, mKeyguardStateController, mKeyguardUpdateMonitor,
+                mScreenLifecycle, mSysUiState, mProtoTracer, mWakefulnessLifecycle,
+                mUserInfoController, mSysUiMainExecutor);
     }
 
     @Test
@@ -105,35 +94,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/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/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
index 0631028..91fe035 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
@@ -368,6 +368,7 @@
         }
     }
 
+    @Override
     public void binderDied() {
         synchronized (mLock) {
             // It is possible that this service's package was force stopped during
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/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/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/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index 6063668..dac23a7 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();
@@ -825,7 +819,7 @@
             @NonNull String packageName);
 
     /**
-     * Returns {@code true} if the the signing information for {@code clientUid} is sufficient
+     * Returns {@code true} if the signing information for {@code clientUid} is sufficient
      * to gain access gated by {@code capability}.  This can happen if the two UIDs have the
      * same signing information, if the signing information {@code clientUid} indicates that
      * it has the signing certificate for {@code serverUid} in its signing history (if it was
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 7cf790a..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/",
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/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..18d5194 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);
     }
@@ -9181,11 +9185,8 @@
                 Settings.Secure.SPATIAL_AUDIO_ENABLED, UserHandle.USER_CURRENT);
         if (settings == null) {
             Log.e(TAG, "error reading spatial audio device settings");
-        } else {
-            Log.v(TAG, "restoring spatial audio device settings: " + settings);
-            mSpatializerHelper.setSADeviceSettings(settings);
         }
-        mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect);
+        mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect, settings);
         mSpatializerHelper.setFeatureEnabled(mHasSpatializerEffect);
     }
 
@@ -9268,9 +9269,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 +9309,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 +10374,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 +10823,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 +11029,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 +11588,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 +11691,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 +11702,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 +11723,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 +11734,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 73e4cf2..d9037fe 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -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/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index dd44af1..cd5960f 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -175,7 +175,7 @@
         mASA = asa;
     }
 
-    synchronized void init(boolean effectExpected) {
+    synchronized void init(boolean effectExpected, @Nullable String settings) {
         loglogi("init effectExpected=" + effectExpected);
         if (!effectExpected) {
             loglogi("init(): setting state to STATE_NOT_SUPPORTED due to effect not expected");
@@ -278,6 +278,13 @@
                     mSACapableDeviceTypes.add(SPAT_MODE_FOR_DEVICE_TYPE.keyAt(i));
                 }
             }
+
+            // When initialized from AudioService, the settings string will be non-null.
+            // Saved settings need to be applied after spatialization support is initialized above.
+            if (settings != null) {
+                setSADeviceSettings(settings);
+            }
+
             // for both transaural / binaural, we are not forcing enablement as the init() method
             // could have been called another time after boot in case of audioserver restart
             addCompatibleAudioDevice(
@@ -316,7 +323,7 @@
         mState = STATE_UNINITIALIZED;
         mSpatLevel = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE;
         mActualHeadTrackingMode = Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED;
-        init(true);
+        init(true, null /* settings */);
         setSpatializerEnabledInt(featureEnabled);
     }
 
@@ -731,7 +738,7 @@
                 return;
             }
             if (mState == STATE_UNINITIALIZED) {
-                init(true);
+                init(true, null /* settings */);
             }
             setSpatializerEnabledInt(true);
         } else {
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/UsageStats.java b/services/core/java/com/android/server/biometrics/sensors/face/UsageStats.java
index d99abcd..9494547 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/UsageStats.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/UsageStats.java
@@ -70,20 +70,24 @@
 
     private int mAcceptCount;
     private int mRejectCount;
-    private SparseIntArray mErrorCount;
+    private int mErrorCount;
+    private int mAuthAttemptCount;
+    private SparseIntArray mErrorFrequencyMap;
 
     private long mAcceptLatency;
     private long mRejectLatency;
-    private SparseLongArray mErrorLatency;
+    private long mErrorLatency;
+    private SparseLongArray mErrorLatencyMap;
 
     public UsageStats(Context context) {
         mAuthenticationEvents = new ArrayDeque<>();
-        mErrorCount = new SparseIntArray();
-        mErrorLatency = new SparseLongArray();
+        mErrorFrequencyMap = new SparseIntArray();
+        mErrorLatencyMap = new SparseLongArray();
         mContext = context;
     }
 
     public void addEvent(AuthenticationEvent event) {
+        mAuthAttemptCount++;
         if (mAuthenticationEvents.size() >= EVENT_LOG_SIZE) {
             mAuthenticationEvents.removeFirst();
         }
@@ -96,29 +100,38 @@
             mRejectCount++;
             mRejectLatency += event.mLatency;
         } else {
-            mErrorCount.put(event.mError, mErrorCount.get(event.mError, 0) + 1);
-            mErrorLatency.put(event.mError, mErrorLatency.get(event.mError, 0L) + event.mLatency);
+            mErrorCount++;
+            mErrorLatency += event.mLatency;
+            mErrorFrequencyMap.put(event.mError, mErrorFrequencyMap.get(event.mError, 0) + 1);
+            mErrorLatencyMap.put(event.mError,
+                    mErrorLatencyMap.get(event.mError, 0L) + event.mLatency);
         }
     }
 
     public void print(PrintWriter pw) {
-        pw.println("Events since last reboot: " + mAuthenticationEvents.size());
+        pw.println("Printing most recent events since last reboot("
+                + mAuthenticationEvents.size() + " events)");
         for (AuthenticationEvent event : mAuthenticationEvents) {
             pw.println(event.toString(mContext));
         }
 
         // Dump aggregated usage stats
-        pw.println("Accept\tCount: " + mAcceptCount + "\tLatency: " + mAcceptLatency
+        pw.println("");
+        pw.println("Accept Count: " + mAcceptCount + "\tLatency: " + mAcceptLatency
                 + "\tAverage: " + (mAcceptCount > 0 ? mAcceptLatency / mAcceptCount : 0));
-        pw.println("Reject\tCount: " + mRejectCount + "\tLatency: " + mRejectLatency
+        pw.println("Reject Count: " + mRejectCount + "\tLatency: " + mRejectLatency
                 + "\tAverage: " + (mRejectCount > 0 ? mRejectLatency / mRejectCount : 0));
+        pw.println("Total Error Count: " + mErrorCount + "\tLatency: " + mErrorLatency
+                + "\tAverage: " + (mErrorCount > 0 ? mErrorLatency / mErrorCount : 0));
+        pw.println("Total Attempts: " + mAuthAttemptCount);
+        pw.println("");
 
-        for (int i = 0; i < mErrorCount.size(); i++) {
-            final int key = mErrorCount.keyAt(i);
-            final int count = mErrorCount.get(i);
+        for (int i = 0; i < mErrorFrequencyMap.size(); i++) {
+            final int key = mErrorFrequencyMap.keyAt(i);
+            final int count = mErrorFrequencyMap.get(key);
             pw.println("Error" + key + "\tCount: " + count
-                    + "\tLatency: " + mErrorLatency.get(key, 0L)
-                    + "\tAverage: " + (count > 0 ? mErrorLatency.get(key, 0L) / count : 0)
+                    + "\tLatency: " + mErrorLatencyMap.get(key, 0L)
+                    + "\tAverage: " + (count > 0 ? mErrorLatencyMap.get(key, 0L) / count : 0)
                     + "\t" + FaceManager.getErrorString(mContext, key, 0 /* vendorCode */));
         }
     }
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/core/java/android/app/timedetector/GnssTimeSuggestion.aidl b/services/core/java/com/android/server/biometrics/sensors/fingerprint/PowerPressHandler.java
similarity index 65%
copy from core/java/android/app/timedetector/GnssTimeSuggestion.aidl
copy to services/core/java/com/android/server/biometrics/sensors/fingerprint/PowerPressHandler.java
index 81475ec..288c372 100644
--- a/core/java/android/app/timedetector/GnssTimeSuggestion.aidl
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/PowerPressHandler.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 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.
@@ -14,6 +14,14 @@
  * limitations under the License.
  */
 
-package android.app.timedetector;
+package com.android.server.biometrics.sensors.fingerprint;
 
-parcelable GnssTimeSuggestion;
+/**
+ * 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/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index 076ac2b..6f9a176 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -43,6 +43,7 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
+import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
@@ -63,6 +64,7 @@
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.SafetyProtectionUtils;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
@@ -1181,9 +1183,19 @@
                 String message =
                         getContext().getString(R.string.pasted_from_clipboard, callingAppLabel);
                 Slog.i(TAG, message);
-                Toast.makeText(
-                        getContext(), UiThread.get().getLooper(), message, Toast.LENGTH_SHORT)
-                        .show();
+                Toast toastToShow;
+                if (SafetyProtectionUtils.shouldShowSafetyProtectionResources(getContext())) {
+                    Drawable safetyProtectionIcon = getContext()
+                            .getDrawable(R.drawable.ic_safety_protection);
+                    toastToShow = Toast.makeCustomToastWithIcon(getContext(),
+                            UiThread.get().getLooper(), message,
+                            Toast.LENGTH_SHORT, safetyProtectionIcon);
+                } else {
+                    toastToShow = Toast.makeText(
+                            getContext(), UiThread.get().getLooper(), message,
+                            Toast.LENGTH_SHORT);
+                }
+                toastToShow.show();
             } catch (PackageManager.NameNotFoundException e) {
                 // do nothing
             }
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 4e5ce8a..774fe5b 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;
 
@@ -3348,7 +3341,7 @@
 
                 // TODO(b/230548427): Remove SDK check once VPN related stuff are
                 //  decoupled from ConnectivityServiceTest.
-                if (SdkLevel.isAtLeastT() && category != null) {
+                if (SdkLevel.isAtLeastT() && category != null && isVpnApp(mPackage)) {
                     sendEventToVpnManagerApp(category, errorClass, errorCode,
                             getPackage(), mSessionKey, makeVpnProfileStateLocked(),
                             mActiveNetwork,
@@ -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/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 6fd8841..114690a 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -46,7 +46,7 @@
 import com.android.internal.display.BrightnessSynchronizer;
 import com.android.internal.os.BackgroundThread;
 import com.android.server.EventLogTags;
-import com.android.server.display.DisplayPowerController.BrightnessEvent;
+import com.android.server.display.brightness.BrightnessEvent;
 
 import java.io.PrintWriter;
 
@@ -337,14 +337,15 @@
 
     float getAutomaticScreenBrightness(BrightnessEvent brightnessEvent) {
         if (brightnessEvent != null) {
-            brightnessEvent.lux =
-                    mAmbientLuxValid ? mAmbientLux : PowerManager.BRIGHTNESS_INVALID_FLOAT;
-            brightnessEvent.preThresholdLux = mPreThresholdLux;
-            brightnessEvent.preThresholdBrightness = mPreThresholdBrightness;
-            brightnessEvent.recommendedBrightness = mScreenAutoBrightness;
-            brightnessEvent.flags |= (!mAmbientLuxValid ? BrightnessEvent.FLAG_INVALID_LUX : 0)
+            brightnessEvent.setLux(
+                    mAmbientLuxValid ? mAmbientLux : PowerManager.BRIGHTNESS_INVALID_FLOAT);
+            brightnessEvent.setPreThresholdLux(mPreThresholdLux);
+            brightnessEvent.setPreThresholdBrightness(mPreThresholdBrightness);
+            brightnessEvent.setRecommendedBrightness(mScreenAutoBrightness);
+            brightnessEvent.setFlags(brightnessEvent.getFlags()
+                    | (!mAmbientLuxValid ? BrightnessEvent.FLAG_INVALID_LUX : 0)
                     | (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE
-                        ? BrightnessEvent.FLAG_DOZE_SCALE : 0);
+                        ? BrightnessEvent.FLAG_DOZE_SCALE : 0));
         }
 
         if (!mAmbientLuxValid) {
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 2322280d..b5aa7b1 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -287,7 +287,8 @@
     private BrightnessThrottlingData mBrightnessThrottlingData;
     private BrightnessThrottlingData mOriginalBrightnessThrottlingData;
 
-    private DisplayDeviceConfig(Context context) {
+    @VisibleForTesting
+    DisplayDeviceConfig(Context context) {
         mContext = context;
     }
 
@@ -691,7 +692,8 @@
         return config;
     }
 
-    private boolean initFromFile(File configFile) {
+    @VisibleForTesting
+    boolean initFromFile(File configFile) {
         if (!configFile.exists()) {
             // Display configuration files aren't required to exist.
             return false;
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 95c8fef..4e33fd0 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -67,6 +67,8 @@
 import com.android.server.LocalServices;
 import com.android.server.am.BatteryStatsService;
 import com.android.server.display.RampAnimator.DualRampAnimator;
+import com.android.server.display.brightness.BrightnessEvent;
+import com.android.server.display.brightness.BrightnessReason;
 import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
 import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener;
 import com.android.server.display.utils.SensorUtils;
@@ -76,7 +78,6 @@
 import com.android.server.policy.WindowManagerPolicy;
 
 import java.io.PrintWriter;
-import java.util.Objects;
 
 /**
  * Controls the power state of the display.
@@ -1430,7 +1431,7 @@
         // we broadcast this change through setting.
         final float unthrottledBrightnessState = brightnessState;
         if (mBrightnessThrottler.isThrottled()) {
-            mTempBrightnessEvent.thermalMax = mBrightnessThrottler.getBrightnessCap();
+            mTempBrightnessEvent.setThermalMax(mBrightnessThrottler.getBrightnessCap());
             brightnessState = Math.min(brightnessState, mBrightnessThrottler.getBrightnessCap());
             mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_THROTTLED);
             if (!mAppliedThrottling) {
@@ -1551,8 +1552,9 @@
             // TODO(b/216365040): The decision to prevent HBM for HDR in low power mode should be
             // done in HighBrightnessModeController.
             if (mHbmController.getHighBrightnessMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
-                    && ((mBrightnessReason.modifier & BrightnessReason.MODIFIER_DIMMED) == 0
-                    || (mBrightnessReason.modifier & BrightnessReason.MODIFIER_LOW_POWER) == 0)) {
+                    && ((mBrightnessReason.getModifier() & BrightnessReason.MODIFIER_DIMMED) == 0
+                    || (mBrightnessReason.getModifier() & BrightnessReason.MODIFIER_LOW_POWER)
+                    == 0)) {
                 // We want to scale HDR brightness level with the SDR level
                 animateValue = mHbmController.getHdrBrightnessValue();
             }
@@ -1615,7 +1617,7 @@
                     + mBrightnessReasonTemp.toString(brightnessAdjustmentFlags)
                     + "', previous reason: '" + mBrightnessReason + "'.");
             mBrightnessReason.set(mBrightnessReasonTemp);
-        } else if (mBrightnessReasonTemp.reason == BrightnessReason.REASON_MANUAL
+        } else if (mBrightnessReasonTemp.getReason() == BrightnessReason.REASON_MANUAL
                 && userSetBrightnessChanged) {
             Slog.v(TAG, "Brightness [" + brightnessState + "] manual adjustment.");
         }
@@ -1624,17 +1626,19 @@
         // Log brightness events when a detail of significance has changed. Generally this is the
         // brightness itself changing, but also includes data like HBM cap, thermal throttling
         // brightness cap, RBC state, etc.
-        mTempBrightnessEvent.time = System.currentTimeMillis();
-        mTempBrightnessEvent.brightness = brightnessState;
-        mTempBrightnessEvent.reason.set(mBrightnessReason);
-        mTempBrightnessEvent.hbmMax = mHbmController.getCurrentBrightnessMax();
-        mTempBrightnessEvent.hbmMode = mHbmController.getHighBrightnessMode();
-        mTempBrightnessEvent.flags |= (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0);
+        mTempBrightnessEvent.setTime(System.currentTimeMillis());
+        mTempBrightnessEvent.setBrightness(brightnessState);
+        mTempBrightnessEvent.setReason(mBrightnessReason);
+        mTempBrightnessEvent.setHbmMax(mHbmController.getCurrentBrightnessMax());
+        mTempBrightnessEvent.setHbmMode(mHbmController.getHighBrightnessMode());
+        mTempBrightnessEvent.setFlags(mTempBrightnessEvent.getFlags()
+                | (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0));
         // Temporary is what we use during slider interactions. We avoid logging those so that
         // we don't spam logcat when the slider is being used.
         boolean tempToTempTransition =
-                mTempBrightnessEvent.reason.reason == BrightnessReason.REASON_TEMPORARY
-                && mLastBrightnessEvent.reason.reason == BrightnessReason.REASON_TEMPORARY;
+                mTempBrightnessEvent.getReason().getReason() == BrightnessReason.REASON_TEMPORARY
+                && mLastBrightnessEvent.getReason().getReason()
+                        == BrightnessReason.REASON_TEMPORARY;
         if ((!mTempBrightnessEvent.equalsMainData(mLastBrightnessEvent) && !tempToTempTransition)
                 || brightnessAdjustmentFlags != 0) {
             mLastBrightnessEvent.copyFrom(mTempBrightnessEvent);
@@ -1642,8 +1646,9 @@
 
             // Adjustment flags (and user-set flag) only get added after the equality checks since
             // they are transient.
-            newEvent.adjustmentFlags = brightnessAdjustmentFlags;
-            newEvent.flags |= (userSetBrightnessChanged ? BrightnessEvent.FLAG_USER_SET : 0);
+            newEvent.setAdjustmentFlags(brightnessAdjustmentFlags);
+            newEvent.setFlags(newEvent.getFlags() | (userSetBrightnessChanged
+                    ? BrightnessEvent.FLAG_USER_SET : 0));
             Slog.i(TAG, newEvent.toString(/* includeTime= */ false));
 
             if (mBrightnessEventRingBuffer != null) {
@@ -2734,117 +2739,7 @@
         }
     }
 
-    class BrightnessEvent {
-        static final int FLAG_RBC = 0x1;
-        static final int FLAG_INVALID_LUX = 0x2;
-        static final int FLAG_DOZE_SCALE = 0x3;
-        static final int FLAG_USER_SET = 0x4;
 
-        public final BrightnessReason reason = new BrightnessReason();
-
-        public int displayId;
-        public float lux;
-        public float preThresholdLux;
-        public long time;
-        public float brightness;
-        public float recommendedBrightness;
-        public float preThresholdBrightness;
-        public float hbmMax;
-        public float thermalMax;
-        public int hbmMode;
-        public int flags;
-        public int adjustmentFlags;
-
-        BrightnessEvent(BrightnessEvent that) {
-            copyFrom(that);
-        }
-
-        BrightnessEvent(int displayId) {
-            this.displayId = displayId;
-            reset();
-        }
-
-        void copyFrom(BrightnessEvent that) {
-            displayId = that.displayId;
-            time = that.time;
-            lux = that.lux;
-            preThresholdLux = that.preThresholdLux;
-            brightness = that.brightness;
-            recommendedBrightness = that.recommendedBrightness;
-            preThresholdBrightness = that.preThresholdBrightness;
-            hbmMax = that.hbmMax;
-            thermalMax = that.thermalMax;
-            flags = that.flags;
-            hbmMode = that.hbmMode;
-            reason.set(that.reason);
-            adjustmentFlags = that.adjustmentFlags;
-        }
-
-        void reset() {
-            time = SystemClock.uptimeMillis();
-            brightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
-            recommendedBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
-            lux = 0;
-            preThresholdLux = 0;
-            preThresholdBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
-            hbmMax = PowerManager.BRIGHTNESS_MAX;
-            thermalMax = PowerManager.BRIGHTNESS_MAX;
-            flags = 0;
-            hbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
-            reason.set(null);
-            adjustmentFlags = 0;
-        }
-
-        boolean equalsMainData(BrightnessEvent that) {
-            // This equals comparison purposefully ignores time since it is regularly changing and
-            // we don't want to log a brightness event just because the time changed.
-            return displayId == that.displayId
-                    && Float.floatToRawIntBits(brightness)
-                        == Float.floatToRawIntBits(that.brightness)
-                    && Float.floatToRawIntBits(recommendedBrightness)
-                        == Float.floatToRawIntBits(that.recommendedBrightness)
-                    && Float.floatToRawIntBits(preThresholdBrightness)
-                        == Float.floatToRawIntBits(that.preThresholdBrightness)
-                    && Float.floatToRawIntBits(lux) == Float.floatToRawIntBits(that.lux)
-                    && Float.floatToRawIntBits(preThresholdLux)
-                        == Float.floatToRawIntBits(that.preThresholdLux)
-                    && Float.floatToRawIntBits(hbmMax) == Float.floatToRawIntBits(that.hbmMax)
-                    && hbmMode == that.hbmMode
-                    && Float.floatToRawIntBits(thermalMax)
-                        == Float.floatToRawIntBits(that.thermalMax)
-                    && flags == that.flags
-                    && adjustmentFlags == that.adjustmentFlags
-                    && reason.equals(that.reason);
-        }
-
-        public String toString(boolean includeTime) {
-            return (includeTime ? TimeUtils.formatForLogging(time) + " - " : "")
-                    + "BrightnessEvent: "
-                    + "disp=" + displayId
-                    + ", brt=" + brightness + ((flags & FLAG_USER_SET) != 0 ? "(user_set)" : "")
-                    + ", rcmdBrt=" + recommendedBrightness
-                    + ", preBrt=" + preThresholdBrightness
-                    + ", lux=" + lux
-                    + ", preLux=" + preThresholdLux
-                    + ", hbmMax=" + hbmMax
-                    + ", hbmMode=" + BrightnessInfo.hbmToString(hbmMode)
-                    + ", thrmMax=" + thermalMax
-                    + ", flags=" + flagsToString()
-                    + ", reason=" + reason.toString(adjustmentFlags);
-        }
-
-        @Override
-        public String toString() {
-            return toString(/* includeTime */ true);
-        }
-
-        private String flagsToString() {
-            return ((flags & FLAG_USER_SET) != 0 ? "user_set " : "")
-                    + ((flags & FLAG_RBC) != 0 ? "rbc " : "")
-                    + ((flags & FLAG_INVALID_LUX) != 0 ? "invalid_lux " : "")
-                    + ((flags & FLAG_DOZE_SCALE) != 0 ? "doze_scale " : "");
-        }
-    }
 
     private final class DisplayControllerHandler extends Handler {
         public DisplayControllerHandler(Looper looper) {
@@ -2996,137 +2891,6 @@
         }
     }
 
-    /**
-     * Stores data about why the brightness was changed.  Made up of one main
-     * {@code BrightnessReason.REASON_*} reason and various {@code BrightnessReason.MODIFIER_*}
-     * modifiers.
-     */
-    private final class BrightnessReason {
-        static final int REASON_UNKNOWN = 0;
-        static final int REASON_MANUAL = 1;
-        static final int REASON_DOZE = 2;
-        static final int REASON_DOZE_DEFAULT = 3;
-        static final int REASON_AUTOMATIC = 4;
-        static final int REASON_SCREEN_OFF = 5;
-        static final int REASON_VR = 6;
-        static final int REASON_OVERRIDE = 7;
-        static final int REASON_TEMPORARY = 8;
-        static final int REASON_BOOST = 9;
-        static final int REASON_MAX = REASON_BOOST;
-
-        static final int MODIFIER_DIMMED = 0x1;
-        static final int MODIFIER_LOW_POWER = 0x2;
-        static final int MODIFIER_HDR = 0x4;
-        static final int MODIFIER_THROTTLED = 0x8;
-        static final int MODIFIER_MASK = MODIFIER_DIMMED | MODIFIER_LOW_POWER | MODIFIER_HDR
-            | MODIFIER_THROTTLED;
-
-        // ADJUSTMENT_*
-        // These things can happen at any point, even if the main brightness reason doesn't
-        // fundamentally change, so they're not stored.
-
-        // Auto-brightness adjustment factor changed
-        static final int ADJUSTMENT_AUTO_TEMP = 0x1;
-        // Temporary adjustment to the auto-brightness adjustment factor.
-        static final int ADJUSTMENT_AUTO = 0x2;
-
-        // One of REASON_*
-        public int reason;
-        // Any number of MODIFIER_*
-        public int modifier;
-
-        public void set(BrightnessReason other) {
-            setReason(other == null ? REASON_UNKNOWN : other.reason);
-            setModifier(other == null ? 0 : other.modifier);
-        }
-
-        public void setReason(int reason) {
-            if (reason < REASON_UNKNOWN || reason > REASON_MAX) {
-                Slog.w(TAG, "brightness reason out of bounds: " + reason);
-            } else {
-                this.reason = reason;
-            }
-        }
-
-        public void setModifier(int modifier) {
-            if ((modifier & ~MODIFIER_MASK) != 0) {
-                Slog.w(TAG, "brightness modifier out of bounds: 0x"
-                        + Integer.toHexString(modifier));
-            } else {
-                this.modifier = modifier;
-            }
-        }
-
-        public void addModifier(int modifier) {
-            setModifier(modifier | this.modifier);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (!(obj instanceof BrightnessReason)) {
-                return false;
-            }
-            BrightnessReason other = (BrightnessReason) obj;
-            return other.reason == reason && other.modifier == modifier;
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(reason, modifier);
-        }
-
-        @Override
-        public String toString() {
-            return toString(0);
-        }
-
-        public String toString(int adjustments) {
-            final StringBuilder sb = new StringBuilder();
-            sb.append(reasonToString(reason));
-            sb.append(" [");
-            if ((adjustments & ADJUSTMENT_AUTO_TEMP) != 0) {
-                sb.append(" temp_adj");
-            }
-            if ((adjustments & ADJUSTMENT_AUTO) != 0) {
-                sb.append(" auto_adj");
-            }
-            if ((modifier & MODIFIER_LOW_POWER) != 0) {
-                sb.append(" low_pwr");
-            }
-            if ((modifier & MODIFIER_DIMMED) != 0) {
-                sb.append(" dim");
-            }
-            if ((modifier & MODIFIER_HDR) != 0) {
-                sb.append(" hdr");
-            }
-            if ((modifier & MODIFIER_THROTTLED) != 0) {
-                sb.append(" throttled");
-            }
-            int strlen = sb.length();
-            if (sb.charAt(strlen - 1) == '[') {
-                sb.setLength(strlen - 2);
-            } else {
-                sb.append(" ]");
-            }
-            return sb.toString();
-        }
-
-        private String reasonToString(int reason) {
-            switch (reason) {
-                case REASON_MANUAL: return "manual";
-                case REASON_DOZE: return "doze";
-                case REASON_DOZE_DEFAULT: return "doze_default";
-                case REASON_AUTOMATIC: return "automatic";
-                case REASON_SCREEN_OFF: return "screen_off";
-                case REASON_VR: return "vr";
-                case REASON_OVERRIDE: return "override";
-                case REASON_TEMPORARY: return "temporary";
-                case REASON_BOOST: return "boost";
-                default: return Integer.toString(reason);
-            }
-        }
-    }
-
     static class CachedBrightnessInfo {
         public MutableFloat brightness = new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
         public MutableFloat adjustedBrightness =
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/brightness/BrightnessEvent.java b/services/core/java/com/android/server/display/brightness/BrightnessEvent.java
new file mode 100644
index 0000000..6698612
--- /dev/null
+++ b/services/core/java/com/android/server/display/brightness/BrightnessEvent.java
@@ -0,0 +1,262 @@
+/*
+ * 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.display.brightness;
+
+import android.hardware.display.BrightnessInfo;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.util.TimeUtils;
+
+/**
+ * Represents a particular brightness change event.
+ */
+public final class BrightnessEvent {
+    public static final int FLAG_RBC = 0x1;
+    public static final int FLAG_INVALID_LUX = 0x2;
+    public static final int FLAG_DOZE_SCALE = 0x3;
+    public static final int FLAG_USER_SET = 0x4;
+
+    private BrightnessReason mReason = new BrightnessReason();
+    private int mDisplayId;
+    private float mLux;
+    private float mPreThresholdLux;
+    private long mTime;
+    private float mBrightness;
+    private float mRecommendedBrightness;
+    private float mPreThresholdBrightness;
+    private float mHbmMax;
+    private float mThermalMax;
+    private int mHbmMode;
+    private int mFlags;
+    private int mAdjustmentFlags;
+
+    public BrightnessEvent(BrightnessEvent that) {
+        copyFrom(that);
+    }
+
+    public BrightnessEvent(int displayId) {
+        this.mDisplayId = displayId;
+        reset();
+    }
+
+    /**
+     * A utility to clone a brightness event into another event
+     *
+     * @param that BrightnessEvent which is to be copied
+     */
+    public void copyFrom(BrightnessEvent that) {
+        mDisplayId = that.getDisplayId();
+        mTime = that.getTime();
+        mLux = that.getLux();
+        mPreThresholdLux = that.getPreThresholdLux();
+        mBrightness = that.getBrightness();
+        mRecommendedBrightness = that.getRecommendedBrightness();
+        mPreThresholdBrightness = that.getPreThresholdBrightness();
+        mHbmMax = that.getHbmMax();
+        mThermalMax = that.getThermalMax();
+        mFlags = that.getFlags();
+        mHbmMode = that.getHbmMode();
+        mReason.set(that.getReason());
+        mAdjustmentFlags = that.getAdjustmentFlags();
+    }
+
+    /**
+     * A utility to reset the BrightnessEvent to default values
+     */
+    public void reset() {
+        mTime = SystemClock.uptimeMillis();
+        mBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
+        mRecommendedBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
+        mLux = 0;
+        mPreThresholdLux = 0;
+        mPreThresholdBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
+        mHbmMax = PowerManager.BRIGHTNESS_MAX;
+        mThermalMax = PowerManager.BRIGHTNESS_MAX;
+        mFlags = 0;
+        mHbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
+        mReason.set(null);
+        mAdjustmentFlags = 0;
+    }
+
+    /**
+     * A utility to compare two BrightnessEvents. This purposefully ignores comparing time as the
+     * two events might have been created at different times, but essentially hold the same
+     * underlying values
+     *
+     * @param that The brightnessEvent with which the current brightnessEvent is to be compared
+     * @return A boolean value representing if the two events are same or not.
+     */
+    public boolean equalsMainData(BrightnessEvent that) {
+        // This equals comparison purposefully ignores time since it is regularly changing and
+        // we don't want to log a brightness event just because the time changed.
+        return mDisplayId == that.mDisplayId
+                && Float.floatToRawIntBits(mBrightness)
+                == Float.floatToRawIntBits(that.mBrightness)
+                && Float.floatToRawIntBits(mRecommendedBrightness)
+                == Float.floatToRawIntBits(that.mRecommendedBrightness)
+                && Float.floatToRawIntBits(mPreThresholdBrightness)
+                == Float.floatToRawIntBits(that.mPreThresholdBrightness)
+                && Float.floatToRawIntBits(mLux) == Float.floatToRawIntBits(that.mLux)
+                && Float.floatToRawIntBits(mPreThresholdLux)
+                == Float.floatToRawIntBits(that.mPreThresholdLux)
+                && Float.floatToRawIntBits(mHbmMax) == Float.floatToRawIntBits(that.mHbmMax)
+                && mHbmMode == that.mHbmMode
+                && Float.floatToRawIntBits(mThermalMax)
+                == Float.floatToRawIntBits(that.mThermalMax)
+                && mFlags == that.mFlags
+                && mAdjustmentFlags == that.mAdjustmentFlags
+                && mReason.equals(that.mReason);
+    }
+
+    /**
+     * A utility to stringify a BrightnessEvent
+     * @param includeTime Indicates if the time field is to be added in the stringify version of the
+     *                    BrightnessEvent
+     * @return A stringified BrightnessEvent
+     */
+    public String toString(boolean includeTime) {
+        return (includeTime ? TimeUtils.formatForLogging(mTime) + " - " : "")
+                + "BrightnessEvent: "
+                + "disp=" + mDisplayId
+                + ", brt=" + mBrightness + ((mFlags & FLAG_USER_SET) != 0 ? "(user_set)" : "")
+                + ", rcmdBrt=" + mRecommendedBrightness
+                + ", preBrt=" + mPreThresholdBrightness
+                + ", lux=" + mLux
+                + ", preLux=" + mPreThresholdLux
+                + ", hbmMax=" + mHbmMax
+                + ", hbmMode=" + BrightnessInfo.hbmToString(mHbmMode)
+                + ", thrmMax=" + mThermalMax
+                + ", flags=" + flagsToString()
+                + ", reason=" + mReason.toString(mAdjustmentFlags);
+    }
+
+    @Override
+    public String toString() {
+        return toString(/* includeTime */ true);
+    }
+
+    public void setReason(BrightnessReason reason) {
+        this.mReason = reason;
+    }
+
+    public BrightnessReason getReason() {
+        return mReason;
+    }
+
+    public int getDisplayId() {
+        return mDisplayId;
+    }
+
+    public void setDisplayId(int displayId) {
+        this.mDisplayId = displayId;
+    }
+
+    public float getLux() {
+        return mLux;
+    }
+
+    public void setLux(float lux) {
+        this.mLux = lux;
+    }
+
+    public float getPreThresholdLux() {
+        return mPreThresholdLux;
+    }
+
+    public void setPreThresholdLux(float preThresholdLux) {
+        this.mPreThresholdLux = preThresholdLux;
+    }
+
+    public long getTime() {
+        return mTime;
+    }
+
+    public void setTime(long time) {
+        this.mTime = time;
+    }
+
+    public float getBrightness() {
+        return mBrightness;
+    }
+
+    public void setBrightness(float brightness) {
+        this.mBrightness = brightness;
+    }
+
+    public float getRecommendedBrightness() {
+        return mRecommendedBrightness;
+    }
+
+    public void setRecommendedBrightness(float recommendedBrightness) {
+        this.mRecommendedBrightness = recommendedBrightness;
+    }
+
+    public float getPreThresholdBrightness() {
+        return mPreThresholdBrightness;
+    }
+
+    public void setPreThresholdBrightness(float preThresholdBrightness) {
+        this.mPreThresholdBrightness = preThresholdBrightness;
+    }
+
+    public float getHbmMax() {
+        return mHbmMax;
+    }
+
+    public void setHbmMax(float hbmMax) {
+        this.mHbmMax = hbmMax;
+    }
+
+    public float getThermalMax() {
+        return mThermalMax;
+    }
+
+    public void setThermalMax(float thermalMax) {
+        this.mThermalMax = thermalMax;
+    }
+
+    public int getHbmMode() {
+        return mHbmMode;
+    }
+
+    public void setHbmMode(int hbmMode) {
+        this.mHbmMode = hbmMode;
+    }
+
+    public int getFlags() {
+        return mFlags;
+    }
+
+    public void setFlags(int flags) {
+        this.mFlags = flags;
+    }
+
+    public int getAdjustmentFlags() {
+        return mAdjustmentFlags;
+    }
+
+    public void setAdjustmentFlags(int adjustmentFlags) {
+        this.mAdjustmentFlags = adjustmentFlags;
+    }
+
+    private String flagsToString() {
+        return ((mFlags & FLAG_USER_SET) != 0 ? "user_set " : "")
+                + ((mFlags & FLAG_RBC) != 0 ? "rbc " : "")
+                + ((mFlags & FLAG_INVALID_LUX) != 0 ? "invalid_lux " : "")
+                + ((mFlags & FLAG_DOZE_SCALE) != 0 ? "doze_scale " : "");
+    }
+}
diff --git a/services/core/java/com/android/server/display/brightness/BrightnessReason.java b/services/core/java/com/android/server/display/brightness/BrightnessReason.java
new file mode 100644
index 0000000..d8eacd9
--- /dev/null
+++ b/services/core/java/com/android/server/display/brightness/BrightnessReason.java
@@ -0,0 +1,200 @@
+/*
+ * 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.display.brightness;
+
+import android.util.Slog;
+
+import java.util.Objects;
+
+/**
+ * Stores data about why the brightness was changed. Made up of one main
+ * {@code BrightnessReason.REASON_*} reason and various {@code BrightnessReason.MODIFIER_*}
+ * modifiers.
+ */
+public final class BrightnessReason {
+    private static final String TAG = "BrightnessReason";
+
+    public static final int REASON_UNKNOWN = 0;
+    public static final int REASON_MANUAL = 1;
+    public static final int REASON_DOZE = 2;
+    public static final int REASON_DOZE_DEFAULT = 3;
+    public static final int REASON_AUTOMATIC = 4;
+    public static final int REASON_SCREEN_OFF = 5;
+    public static final int REASON_VR = 6;
+    public static final int REASON_OVERRIDE = 7;
+    public static final int REASON_TEMPORARY = 8;
+    public static final int REASON_BOOST = 9;
+    public static final int REASON_MAX = REASON_BOOST;
+
+    public static final int MODIFIER_DIMMED = 0x1;
+    public static final int MODIFIER_LOW_POWER = 0x2;
+    public static final int MODIFIER_HDR = 0x4;
+    public static final int MODIFIER_THROTTLED = 0x8;
+    public static final int MODIFIER_MASK = MODIFIER_DIMMED | MODIFIER_LOW_POWER | MODIFIER_HDR
+            | MODIFIER_THROTTLED;
+
+    // ADJUSTMENT_*
+    // These things can happen at any point, even if the main brightness reason doesn't
+    // fundamentally change, so they're not stored.
+
+    // Auto-brightness adjustment factor changed
+    public static final int ADJUSTMENT_AUTO_TEMP = 0x1;
+    // Temporary adjustment to the auto-brightness adjustment factor.
+    public static final int ADJUSTMENT_AUTO = 0x2;
+
+    // One of REASON_*
+    private int mReason;
+    // Any number of MODIFIER_*
+    private int mModifier;
+
+    /**
+     * A utility to clone a BrightnessReason from another BrightnessReason event
+     *
+     * @param other The BrightnessReason object which is to be cloned
+     */
+    public void set(BrightnessReason other) {
+        setReason(other == null ? REASON_UNKNOWN : other.mReason);
+        setModifier(other == null ? 0 : other.mModifier);
+    }
+
+    /**
+     * A utility to add a modifier to the BrightnessReason object
+     *
+     * @param modifier The modifier which is to be added
+     */
+    public void addModifier(int modifier) {
+        setModifier(modifier | this.mModifier);
+    }
+
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof BrightnessReason)) {
+            return false;
+        }
+        BrightnessReason other = (BrightnessReason) obj;
+        return other.mReason == mReason && other.mModifier == mModifier;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mReason, mModifier);
+    }
+
+    @Override
+    public String toString() {
+        return toString(0);
+    }
+
+    /**
+     * A utility to stringify a BrightnessReason
+     *
+     * @param adjustments Indicates if the adjustments field is to be added in the stringify version
+     *                    of the BrightnessReason
+     * @return A stringified BrightnessReason
+     */
+    public String toString(int adjustments) {
+        final StringBuilder sb = new StringBuilder();
+        sb.append(reasonToString(mReason));
+        sb.append(" [");
+        if ((adjustments & ADJUSTMENT_AUTO_TEMP) != 0) {
+            sb.append(" temp_adj");
+        }
+        if ((adjustments & ADJUSTMENT_AUTO) != 0) {
+            sb.append(" auto_adj");
+        }
+        if ((mModifier & MODIFIER_LOW_POWER) != 0) {
+            sb.append(" low_pwr");
+        }
+        if ((mModifier & MODIFIER_DIMMED) != 0) {
+            sb.append(" dim");
+        }
+        if ((mModifier & MODIFIER_HDR) != 0) {
+            sb.append(" hdr");
+        }
+        if ((mModifier & MODIFIER_THROTTLED) != 0) {
+            sb.append(" throttled");
+        }
+        int strlen = sb.length();
+        if (sb.charAt(strlen - 1) == '[') {
+            sb.setLength(strlen - 2);
+        } else {
+            sb.append(" ]");
+        }
+        return sb.toString();
+    }
+
+    /**
+     * A utility to set the reason of the BrightnessReason object
+     *
+     * @param reason The value to which the reason is to be updated.
+     */
+    public void setReason(int reason) {
+        if (reason < REASON_UNKNOWN || reason > REASON_MAX) {
+            Slog.w(TAG, "brightness reason out of bounds: " + reason);
+        } else {
+            this.mReason = reason;
+        }
+    }
+
+    public int getReason() {
+        return mReason;
+    }
+
+    public int getModifier() {
+        return mModifier;
+    }
+
+    /**
+     * A utility to set the modified of the current BrightnessReason object
+     *
+     * @param modifier The value to which the modifier is to be updated
+     */
+    public void setModifier(int modifier) {
+        if ((modifier & ~MODIFIER_MASK) != 0) {
+            Slog.w(TAG, "brightness modifier out of bounds: 0x"
+                    + Integer.toHexString(modifier));
+        } else {
+            this.mModifier = modifier;
+        }
+    }
+
+    private String reasonToString(int reason) {
+        switch (reason) {
+            case REASON_MANUAL:
+                return "manual";
+            case REASON_DOZE:
+                return "doze";
+            case REASON_DOZE_DEFAULT:
+                return "doze_default";
+            case REASON_AUTOMATIC:
+                return "automatic";
+            case REASON_SCREEN_OFF:
+                return "screen_off";
+            case REASON_VR:
+                return "vr";
+            case REASON_OVERRIDE:
+                return "override";
+            case REASON_TEMPORARY:
+                return "temporary";
+            case REASON_BOOST:
+                return "boost";
+            default:
+                return Integer.toString(reason);
+        }
+    }
+}
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 deea90f..e29f00b 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,10 +60,10 @@
 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;
-import android.annotation.RequiresPermission;
 import android.annotation.UiThread;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
@@ -90,6 +91,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 +120,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 +131,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;
@@ -218,6 +222,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";
@@ -289,6 +295,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;
@@ -348,6 +356,8 @@
     private boolean mNotificationShown;
     @GuardedBy("ImfLock.class")
     private final HandwritingModeController mHwController;
+    @GuardedBy("ImfLock.class")
+    private IntArray mStylusIds;
 
     @GuardedBy("ImfLock.class")
     @Nullable
@@ -357,29 +367,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;
         }
     }
 
@@ -395,7 +405,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))
@@ -426,37 +436,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;
         }
     }
 
@@ -754,7 +764,7 @@
      */
     boolean mBoundToAccessibility;
 
-     /**
+    /**
      * Currently enabled session.
      */
     @GuardedBy("ImfLock.class")
@@ -999,7 +1009,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.
@@ -1007,7 +1017,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()) {
@@ -1130,7 +1140,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)
@@ -1326,7 +1336,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.
@@ -1354,7 +1364,7 @@
         }
 
         @GuardedBy("ImfLock.class")
-        final void addKnownImePackageNameLocked(@NonNull String packageName) {
+        void addKnownImePackageNameLocked(@NonNull String packageName) {
             mKnownImePackageNames.add(packageName);
         }
 
@@ -1377,9 +1387,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) {
@@ -1458,6 +1468,7 @@
         public void onUidRemoved(int uid) {
             synchronized (ImfLock.class) {
                 mLoggedDeniedGetInputMethodWindowVisibleHeightForUid.delete(uid);
+                mLoggedDeniedIsInputMethodPickerShownForTestForUid.delete(uid);
             }
         }
 
@@ -1480,8 +1491,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;
@@ -1501,9 +1512,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)) {
@@ -1609,6 +1620,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;
 
@@ -1766,6 +1781,7 @@
                 com.android.internal.R.array.config_nonPreemptibleInputMethods));
         mHwController = new HandwritingModeController(thread.getLooper(),
                 new InkWindowInitializer());
+        registerDeviceListenerAndCheckStylusSupport();
     }
 
     private final class InkWindowInitializer implements Runnable {
@@ -1841,8 +1857,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);
 
@@ -1859,8 +1877,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
@@ -1887,8 +1907,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;
 
@@ -1898,7 +1920,7 @@
                 // The client is already gone.
                 return;
             }
-            cs.client.scheduleStartInputIfNecessary(mInFullscreenMode);
+            cs.mClient.scheduleStartInputIfNecessary(mInFullscreenMode);
         }
     }
 
@@ -1922,6 +1944,9 @@
         }
     }
 
+    /**
+     * TODO(b/32343335): The entire systemRunning() method needs to be revisited.
+     */
     public void systemRunning(StatusBarManagerService statusBar) {
         synchronized (ImfLock.class) {
             if (DEBUG) {
@@ -2021,7 +2046,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");
@@ -2053,7 +2078,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(
@@ -2075,17 +2103,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(
@@ -2185,21 +2202,20 @@
      * @param imiId if null, returns enabled subtypes for the current {@link InputMethodInfo}.
      * @param allowsImplicitlySelectedSubtypes {@code true} to return the implicitly selected
      *                                         subtypes.
+     * @param userId the user ID to be queried about.
      */
     @Override
     public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String imiId,
-            boolean allowsImplicitlySelectedSubtypes) {
-        final int callingUserId = UserHandle.getCallingUserId();
+            boolean allowsImplicitlySelectedSubtypes, @UserIdInt int userId) {
+        if (UserHandle.getCallingUserId() != userId) {
+            mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+        }
+
         synchronized (ImfLock.class) {
-            final int[] resolvedUserIds = InputMethodUtils.resolveUserId(callingUserId,
-                    mSettings.getCurrentUserId(), null);
-            if (resolvedUserIds.length != 1) {
-                return Collections.emptyList();
-            }
             final long ident = Binder.clearCallingIdentity();
             try {
                 return getEnabledInputMethodSubtypeListLocked(imiId,
-                        allowsImplicitlySelectedSubtypes, resolvedUserIds[0]);
+                        allowsImplicitlySelectedSubtypes, userId);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -2266,8 +2282,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.");
                 }
@@ -2299,7 +2315,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);
 
@@ -2338,8 +2354,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();
@@ -2352,10 +2370,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;
@@ -2397,7 +2415,7 @@
     @NonNull
     InputBindResult attachNewInputLocked(@StartInputReason int startInputReason, boolean initial) {
         if (!mBoundToMethod) {
-            getCurMethodLocked().bindInput(mCurClient.binding);
+            getCurMethodLocked().bindInput(mCurClient.mBinding);
             mBoundToMethod = true;
         }
 
@@ -2406,7 +2424,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);
@@ -2417,17 +2435,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");
@@ -2442,8 +2460,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);
     }
@@ -2466,10 +2484,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;
         }
     }
 
@@ -2537,16 +2555,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) {
@@ -2568,7 +2586,7 @@
         mCurRemoteAccessibilityInputConnection = remoteAccessibilityInputConnection;
         mCurImeDispatcher = imeDispatcher;
         mCurVirtualDisplayToScreenMatrix =
-                getVirtualDisplayToScreenMatrixLocked(cs.selfReportedDisplayId,
+                getVirtualDisplayToScreenMatrixLocked(cs.mSelfReportedDisplayId,
                         mDisplayIdToShowIme);
         mCurEditorInfo = editorInfo;
 
@@ -2587,7 +2605,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
@@ -2663,7 +2681,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 */);
         }
     }
@@ -2775,13 +2793,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;
                     }
@@ -2824,7 +2842,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;
@@ -2834,7 +2852,7 @@
                 clientChannel = channels[1];
             }
 
-            cs.sessionRequested = true;
+            cs.mSessionRequested = true;
 
             final IInputMethodInvoker curMethod = getCurMethodLocked();
             final IInputMethodSessionCallback.Stub callback =
@@ -2877,9 +2895,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")
@@ -2903,18 +2921,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;
             }
         }
     }
@@ -3013,7 +3031,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")
@@ -3036,17 +3054,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();
@@ -3070,8 +3088,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;
             }
@@ -3161,7 +3179,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) {
@@ -3227,7 +3245,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);
@@ -3348,14 +3366,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 {
@@ -3369,41 +3384,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,19 +3434,12 @@
     public void reportPerceptibleAsync(IBinder windowToken, boolean perceptible) {
         Objects.requireNonNull(windowToken, "windowToken must not be null");
         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));
         }
     }
 
@@ -3436,10 +3451,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;
         }
 
@@ -3476,29 +3491,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);
@@ -3512,12 +3510,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;
         }
@@ -3564,7 +3562,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;
     }
 
@@ -3679,7 +3677,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.");
@@ -3691,8 +3689,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:
@@ -3703,19 +3701,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.
@@ -3735,7 +3733,7 @@
         }
 
         if (userId != mSettings.getCurrentUserId()) {
-            scheduleSwitchUserTaskLocked(userId, cs.client);
+            scheduleSwitchUserTaskLocked(userId, cs.mClient);
             return InputBindResult.USER_SWITCHING;
         }
 
@@ -3776,7 +3774,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
@@ -3819,7 +3817,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();
                         }
                     }
@@ -3934,7 +3932,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.
@@ -3965,12 +3963,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())) {
@@ -3983,9 +3984,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);
@@ -3995,21 +3993,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)
@@ -4020,6 +4013,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();
         }
@@ -4052,18 +4057,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) {
@@ -4099,11 +4092,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 =
@@ -4114,7 +4107,7 @@
                                 targetLastImiId = imi.getId();
                                 subtypeId = SubtypeUtils.getSubtypeIdFromHashCode(imi,
                                         keyboardSubtype.hashCode());
-                                if(keyboardSubtype.getLocale().equals(locale)) {
+                                if (keyboardSubtype.getLocale().equals(locale)) {
                                     break;
                                 }
                             }
@@ -4162,36 +4155,25 @@
             final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
                     false /* onlyCurrentIme */, mMethodMap.get(getSelectedMethodIdLocked()),
                     mCurrentSubtype);
-            if (nextSubtype == null) {
-                return false;
-            }
-            return true;
+            return nextSubtype != null;
         }
     }
 
     @Override
-    public InputMethodSubtype getLastInputMethodSubtype() {
+    public InputMethodSubtype getLastInputMethodSubtype(@UserIdInt int userId) {
+        if (UserHandle.getCallingUserId() != userId) {
+            mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+        }
         synchronized (ImfLock.class) {
-            if (!calledFromValidUserLocked()) {
-                return null;
+            if (mSettings.getCurrentUserId() == userId) {
+                return mSettings.getLastInputMethodSubtypeLocked();
             }
-            final Pair<String, String> lastIme = mSettings.getLastInputMethodAndSubtypeLocked();
-            // TODO: Handle the case of the last IME with no subtypes
-            if (lastIme == null || TextUtils.isEmpty(lastIme.first)
-                    || TextUtils.isEmpty(lastIme.second)) return null;
-            final InputMethodInfo lastImi = mMethodMap.get(lastIme.first);
-            if (lastImi == null) return null;
-            try {
-                final int lastSubtypeHash = Integer.parseInt(lastIme.second);
-                final int lastSubtypeId = SubtypeUtils.getSubtypeIdFromHashCode(lastImi,
-                        lastSubtypeHash);
-                if (lastSubtypeId < 0 || lastSubtypeId >= lastImi.getSubtypeCount()) {
-                    return null;
-                }
-                return lastImi.getSubtypeAt(lastSubtypeId);
-            } catch (NumberFormatException e) {
-                return null;
-            }
+
+            final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
+            final InputMethodSettings settings = new InputMethodSettings(
+                    mContext.getResources(), mContext.getContentResolver(), methodMap,
+                    userId, false);
+            return settings.getLastInputMethodSubtypeLocked();
         }
     }
 
@@ -4254,8 +4236,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
@@ -4280,9 +4263,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();
     }
 
@@ -4329,7 +4312,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);
                     }
@@ -4338,12 +4321,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);
@@ -4356,16 +4339,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) {
@@ -4382,10 +4365,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
@@ -4450,7 +4565,7 @@
         }
         for (ClientState state : clients.values()) {
             if (state != null) {
-                state.client.setImeTraceEnabled(true /* enabled */);
+                state.mClient.setImeTraceEnabled(true /* enabled */);
             }
         }
     }
@@ -4465,7 +4580,7 @@
         }
         for (ClientState state : clients.values()) {
             if (state != null) {
-                state.client.setImeTraceEnabled(false /* enabled */);
+                state.mClient.setImeTraceEnabled(false /* enabled */);
             }
         }
     }
@@ -4544,7 +4659,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.
@@ -4562,6 +4677,7 @@
                 Slog.w(TAG, "IME requested to finish handwriting with a mismatched requestId: "
                         + requestId);
             }
+            removeVirtualStylusIdForTestSessionLocked();
             scheduleResetStylusHandwriting();
         }
     }
@@ -4574,7 +4690,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()
@@ -4642,14 +4758,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);
             }
         }
     }
@@ -4728,9 +4844,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) {
                     }
@@ -4742,8 +4858,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) {
                     }
@@ -4795,7 +4911,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();
@@ -4852,8 +4969,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()));
             }
@@ -4963,8 +5080,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);
@@ -4978,8 +5095,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;
@@ -5007,8 +5124,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);
@@ -5089,23 +5206,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}.
      *
@@ -5267,7 +5367,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);
@@ -5278,8 +5378,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);
@@ -5402,10 +5501,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();
+                }
             }
         }
 
@@ -5433,18 +5534,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);
                 }
             }
         }
@@ -5455,11 +5556,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
@@ -5525,7 +5626,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);
@@ -5547,9 +5648,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);
             }
         }
     }
@@ -5627,9 +5728,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, "    ");
@@ -5639,20 +5740,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()
@@ -5673,6 +5774,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:");
@@ -5694,7 +5797,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);
             }
@@ -5710,7 +5813,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);
             }
@@ -5766,22 +5869,10 @@
             mService = service;
         }
 
-        @RequiresPermission(allOf = {
-                Manifest.permission.DUMP,
-                Manifest.permission.INTERACT_ACROSS_USERS_FULL,
-                Manifest.permission.WRITE_SECURE_SETTINGS,
-        })
         @BinderThread
         @ShellCommandResult
         @Override
         public int onCommand(@Nullable String cmd) {
-            // For shell command, require all the permissions here in favor of code simplicity.
-            Arrays.asList(
-                    Manifest.permission.DUMP,
-                    Manifest.permission.INTERACT_ACROSS_USERS_FULL,
-                    Manifest.permission.WRITE_SECURE_SETTINGS
-            ).forEach(permission -> mService.mContext.enforceCallingPermission(permission, null));
-
             final long identity = Binder.clearCallingIdentity();
             try {
                 return onCommandWithSystemIdentity(cmd);
@@ -5948,25 +6039,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, "  ");
+                        }
                     }
                 }
             }
@@ -5976,8 +6068,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
@@ -5986,18 +6079,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;
@@ -6089,7 +6183,6 @@
                     + " failed due to its unrecognized IME ID.");
             return false;
         }
-
         out.print("Input method ");
         out.print(imeId);
         out.print(": ");
@@ -6102,6 +6195,7 @@
 
     /**
      * Handles {@code adb shell ime set}.
+     *
      * @param shellCommand {@link ShellCommand} object that is handling this command.
      * @return Exit code of the command.
      */
@@ -6110,32 +6204,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;
@@ -6149,70 +6245,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;
@@ -6227,23 +6325,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;
@@ -6252,7 +6353,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..e37a8e0 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(
@@ -592,6 +592,27 @@
             return getLastSubtypeForInputMethodLockedInternal(null);
         }
 
+        @Nullable
+        InputMethodSubtype getLastInputMethodSubtypeLocked() {
+            final Pair<String, String> lastIme = getLastInputMethodAndSubtypeLocked();
+            // TODO: Handle the case of the last IME with no subtypes
+            if (lastIme == null || TextUtils.isEmpty(lastIme.first)
+                    || TextUtils.isEmpty(lastIme.second)) return null;
+            final InputMethodInfo lastImi = mMethodMap.get(lastIme.first);
+            if (lastImi == null) return null;
+            try {
+                final int lastSubtypeHash = Integer.parseInt(lastIme.second);
+                final int lastSubtypeId = SubtypeUtils.getSubtypeIdFromHashCode(lastImi,
+                        lastSubtypeHash);
+                if (lastSubtypeId < 0 || lastSubtypeId >= lastImi.getSubtypeCount()) {
+                    return null;
+                }
+                return lastImi.getSubtypeAt(lastSubtypeId);
+            } catch (NumberFormatException e) {
+                return null;
+            }
+        }
+
         String getLastSubtypeForInputMethodLocked(String imeId) {
             Pair<String, String> ime = getLastSubtypeForInputMethodLockedInternal(imeId);
             if (ime != null) {
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..8c03ead 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -16,7 +16,6 @@
 
 package com.android.server.location;
 
-import static android.Manifest.permission.ACCESS_FINE_LOCATION;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
 import static android.app.compat.CompatChanges.isChangeEnabled;
@@ -430,7 +429,9 @@
 
         // initialize gnss last because it has no awareness of boot phases and blindly assumes that
         // all other location providers are loaded at initialization
-        if (GnssNative.isSupported()) {
+        boolean hasLocationFeature = mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_LOCATION);
+        if (hasLocationFeature && GnssNative.isSupported()) {
             GnssConfiguration gnssConfiguration = new GnssConfiguration(mContext);
             GnssNative gnssNative = GnssNative.create(mInjector, gnssConfiguration);
             mGnssManagerService = new GnssManagerService(mContext, mInjector, gnssNative);
@@ -938,10 +939,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 +1150,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 +1165,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 +1222,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 +1235,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 c047686..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.
          */
@@ -341,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());
     }
 
@@ -557,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.
@@ -585,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();
@@ -631,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)
@@ -784,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 = "
@@ -847,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();
         }
     }
@@ -879,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) {
@@ -936,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 7100ac8..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;
diff --git a/services/core/java/com/android/server/location/gnss/GnssConfiguration.java b/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
index 12f8776..1435016 100644
--- a/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
+++ b/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
@@ -21,6 +21,7 @@
 import android.os.SystemProperties;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -73,6 +74,8 @@
     static final String CONFIG_NFW_PROXY_APPS = "NFW_PROXY_APPS";
     private static final String CONFIG_ENABLE_PSDS_PERIODIC_DOWNLOAD =
             "ENABLE_PSDS_PERIODIC_DOWNLOAD";
+    private static final String CONFIG_ENABLE_ACTIVE_SIM_EMERGENCY_SUPL =
+            "ENABLE_ACTIVE_SIM_EMERGENCY_SUPL";
     static final String CONFIG_LONGTERM_PSDS_SERVER_1 = "LONGTERM_PSDS_SERVER_1";
     static final String CONFIG_LONGTERM_PSDS_SERVER_2 = "LONGTERM_PSDS_SERVER_2";
     static final String CONFIG_LONGTERM_PSDS_SERVER_3 = "LONGTERM_PSDS_SERVER_3";
@@ -207,6 +210,14 @@
     }
 
     /**
+     * Returns true if during an emergency call, the GnssConfiguration of the activeSubId will be
+     * injected for the emergency SUPL flow; Returns false otherwise. Default false if not set.
+     */
+    boolean isActiveSimEmergencySuplEnabled() {
+        return getBooleanConfig(CONFIG_ENABLE_ACTIVE_SIM_EMERGENCY_SUPL, false);
+    }
+
+    /**
      * Returns true if a long-term PSDS server is configured.
      */
     boolean isLongTermPsdsServerConfigured() {
@@ -232,16 +243,31 @@
 
     /**
      * Loads the GNSS properties from carrier config file followed by the properties from
-     * gps debug config file.
+     * gps debug config file, and injects the GNSS properties into the HAL.
      */
     void reloadGpsProperties() {
-        if (DEBUG) Log.d(TAG, "Reset GPS properties, previous size = " + mProperties.size());
-        loadPropertiesFromCarrierConfig();
+        reloadGpsProperties(/* inEmergency= */ false, /* activeSubId= */ -1);
+    }
 
-        String lpp_prof = SystemProperties.get(LPP_PROFILE);
-        if (!TextUtils.isEmpty(lpp_prof)) {
-            // override default value of this if lpp_prof is not empty
-            mProperties.setProperty(CONFIG_LPP_PROFILE, lpp_prof);
+    /**
+     * Loads the GNSS properties from carrier config file followed by the properties from
+     * gps debug config file, and injects the GNSS properties into the HAL.
+     */
+    void reloadGpsProperties(boolean inEmergency, int activeSubId) {
+        if (DEBUG) {
+            Log.d(TAG,
+                    "Reset GPS properties, previous size = " + mProperties.size() + ", inEmergency:"
+                            + inEmergency + ", activeSubId=" + activeSubId);
+        }
+        loadPropertiesFromCarrierConfig(inEmergency, activeSubId);
+
+        if (isSimAbsent(mContext)) {
+            // Use the default SIM's LPP profile when SIM is absent.
+            String lpp_prof = SystemProperties.get(LPP_PROFILE);
+            if (!TextUtils.isEmpty(lpp_prof)) {
+                // override default value of this if lpp_prof is not empty
+                mProperties.setProperty(CONFIG_LPP_PROFILE, lpp_prof);
+            }
         }
 
         /*
@@ -322,16 +348,19 @@
     /**
      * Loads GNSS properties from carrier config file.
      */
-    void loadPropertiesFromCarrierConfig() {
+    void loadPropertiesFromCarrierConfig(boolean inEmergency, int activeSubId) {
         CarrierConfigManager configManager = (CarrierConfigManager)
                 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
         if (configManager == null) {
             return;
         }
 
-        int ddSubId = SubscriptionManager.getDefaultDataSubscriptionId();
-        PersistableBundle configs = SubscriptionManager.isValidSubscriptionId(ddSubId)
-                ? configManager.getConfigForSubId(ddSubId) : configManager.getConfig();
+        int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+        if (inEmergency && activeSubId >= 0) {
+            subId = activeSubId;
+        }
+        PersistableBundle configs = SubscriptionManager.isValidSubscriptionId(subId)
+                ? configManager.getConfigForSubId(subId) : configManager.getConfig();
         if (configs == null) {
             if (DEBUG) Log.d(TAG, "SIM not ready, use default carrier config.");
             configs = CarrierConfigManager.getDefaultConfig();
@@ -422,6 +451,12 @@
         return gnssConfiguartionIfaceVersion.mMajor < 2;
     }
 
+    private static boolean isSimAbsent(Context context) {
+        TelephonyManager phone = (TelephonyManager) context.getSystemService(
+                Context.TELEPHONY_SERVICE);
+        return phone.getSimState() == TelephonyManager.SIM_STATE_ABSENT;
+    }
+
     private static native HalInterfaceVersion native_get_gnss_configuration_version();
 
     private static native boolean native_set_supl_version(int version);
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index f5c2bbc..a6a3db1 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -126,6 +126,7 @@
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
 
 /**
  * A GNSS implementation of LocationProvider used by LocationManager.
@@ -359,8 +360,9 @@
                 }
             }
             if (isKeepLppProfile) {
-                // load current properties for the carrier
-                mGnssConfiguration.loadPropertiesFromCarrierConfig();
+                // load current properties for the carrier of ddSubId
+                mGnssConfiguration.loadPropertiesFromCarrierConfig(/* inEmergency= */ false,
+                        /* activeSubId= */ -1);
                 String lpp_profile = mGnssConfiguration.getLppProfile();
                 // set the persist property LPP_PROFILE for the value
                 if (lpp_profile != null) {
@@ -431,13 +433,38 @@
         // this approach is just fine because events are posted to our handler anyway
         mGnssConfiguration = mGnssNative.getConfiguration();
         // Create a GPS net-initiated handler (also needed by handleInitialize)
+        GpsNetInitiatedHandler.EmergencyCallCallback emergencyCallCallback =
+                new GpsNetInitiatedHandler.EmergencyCallCallback() {
+
+                    @Override
+                    public void onEmergencyCallStart(int subId) {
+                        if (!mGnssConfiguration.isActiveSimEmergencySuplEnabled()) {
+                            return;
+                        }
+                        mHandler.post(() -> mGnssConfiguration.reloadGpsProperties(
+                                mNIHandler.getInEmergency(), subId));
+                    }
+
+                    @Override
+                    public void onEmergencyCallEnd() {
+                        if (!mGnssConfiguration.isActiveSimEmergencySuplEnabled()) {
+                            return;
+                        }
+                        mHandler.postDelayed(() -> mGnssConfiguration.reloadGpsProperties(
+                                        /* inEmergency= */ false,
+                                        SubscriptionManager.getDefaultDataSubscriptionId()),
+                                TimeUnit.SECONDS.toMillis(mGnssConfiguration.getEsExtensionSec()));
+                    }
+                };
         mNIHandler = new GpsNetInitiatedHandler(context,
                 mNetInitiatedListener,
+                emergencyCallCallback,
                 mSuplEsEnabled);
         // Trigger PSDS data download when the network comes up after booting.
         mPendingDownloadPsdsTypes.add(GnssPsdsDownloader.LONG_TERM_PSDS_SERVER_INDEX);
         mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(context,
-                GnssLocationProvider.this::onNetworkAvailable, mHandler.getLooper(), mNIHandler);
+                GnssLocationProvider.this::onNetworkAvailable,
+                mHandler.getLooper(), mNIHandler);
 
         mNtpTimeHelper = new NtpTimeHelper(mContext, mHandler.getLooper(), this);
         mGnssSatelliteBlocklistHelper =
@@ -1694,9 +1721,12 @@
         int type = AGPS_SETID_TYPE_NONE;
         String setId = null;
 
-        int ddSubId = SubscriptionManager.getDefaultDataSubscriptionId();
-        if (SubscriptionManager.isValidSubscriptionId(ddSubId)) {
-            phone = phone.createForSubscriptionId(ddSubId);
+        int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+        if (mNIHandler.getInEmergency() && mNetworkConnectivityHandler.getActiveSubId() >= 0) {
+            subId = mNetworkConnectivityHandler.getActiveSubId();
+        }
+        if (SubscriptionManager.isValidSubscriptionId(subId)) {
+            phone = phone.createForSubscriptionId(subId);
         }
         if ((flags & AGPS_REQUEST_SETID_IMSI) == AGPS_REQUEST_SETID_IMSI) {
             setId = phone.getSubscriberId();
diff --git a/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
index aba7572..6f890cd 100644
--- a/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
+++ b/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
@@ -190,7 +190,7 @@
         mContext = context;
         mGnssNetworkListener = gnssNetworkListener;
 
-    SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
+        SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
         if (subManager != null) {
             subManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangeListener);
         }
@@ -311,6 +311,13 @@
     }
 
     /**
+     * Returns the active Sub ID for emergency SUPL connection.
+     */
+    int getActiveSubId() {
+        return mActiveSubId;
+    }
+
+    /**
      * Called from native code to update AGPS connection status, or to request or release a SUPL
      * connection.
      *
diff --git a/services/core/java/com/android/server/location/gnss/NtpTimeHelper.java b/services/core/java/com/android/server/location/gnss/NtpTimeHelper.java
index 8732065..e4bc788 100644
--- a/services/core/java/com/android/server/location/gnss/NtpTimeHelper.java
+++ b/services/core/java/com/android/server/location/gnss/NtpTimeHelper.java
@@ -29,8 +29,6 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
-import java.util.Date;
-
 /**
  * Handles inject NTP time to GNSS.
  *
@@ -194,18 +192,18 @@
             return false;
         }
 
-        long time = ntpResult.getTimeMillis();
-        long timeReference = ntpResult.getElapsedRealtimeMillis();
-        long certainty = ntpResult.getCertaintyMillis();
-
+        long unixEpochTimeMillis = ntpResult.getTimeMillis();
+        long timeReferenceMillis = ntpResult.getElapsedRealtimeMillis();
+        int uncertaintyMillis = ntpResult.getUncertaintyMillis();
         if (DEBUG) {
-            long now = System.currentTimeMillis();
-            Log.d(TAG, "NTP server returned: " + time + " (" + new Date(time) + ")"
-                    + " ntpResult: " + ntpResult + " system time offset: " + (time - now));
+            long currentTimeMillis = System.currentTimeMillis();
+            Log.d(TAG, "NTP server returned: " + unixEpochTimeMillis
+                    + " ntpResult: " + ntpResult
+                    + " system time offset: " + (unixEpochTimeMillis - currentTimeMillis));
         }
 
-        // Ok to cast to int, as can't rollover in practice
-        mHandler.post(() -> mCallback.injectTime(time, timeReference, (int) certainty));
+        mHandler.post(() -> mCallback.injectTime(unixEpochTimeMillis, timeReferenceMillis,
+                uncertaintyMillis));
         return true;
     }
 }
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index ee8a23c..884ae171 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -33,10 +33,10 @@
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD_OR_PIN;
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
+import static com.android.internal.widget.LockPatternUtils.CURRENT_LSKF_BASED_PROTECTOR_ID_KEY;
 import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
 import static com.android.internal.widget.LockPatternUtils.PROFILE_KEY_NAME_DECRYPT;
 import static com.android.internal.widget.LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT;
-import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE;
 import static com.android.internal.widget.LockPatternUtils.USER_FRP;
@@ -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;
@@ -140,12 +139,10 @@
 import com.android.server.SystemService;
 import com.android.server.locksettings.LockSettingsStorage.PersistentData;
 import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationResult;
-import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationToken;
+import com.android.server.locksettings.SyntheticPasswordManager.SyntheticPassword;
 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;
@@ -202,8 +199,8 @@
 
     private static final int PROFILE_KEY_IV_SIZE = 12;
     private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
-    private static final String PREV_SYNTHETIC_PASSWORD_HANDLE_KEY = "prev-sp-handle";
-    private static final String SYNTHETIC_PASSWORD_UPDATE_TIME_KEY = "sp-handle-ts";
+    private static final String PREV_LSKF_BASED_PROTECTOR_ID_KEY = "prev-sp-handle";
+    private static final String LSKF_LAST_CHANGED_TIME_KEY = "sp-handle-ts";
     private static final String USER_SERIAL_NUMBER_KEY = "serial-number";
 
     // Duration that LockSettingsService will store the gatekeeper password for. This allows
@@ -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();
     }
 
     /**
@@ -807,28 +787,28 @@
                 // credential and still needs to be passed to the HAL once that credential is
                 // removed.
                 if (mUserManager.getUserInfo(userId).isPrimary() && !isUserSecure(userId)) {
-                    tryDeriveAuthTokenForUnsecuredPrimaryUser(userId);
+                    tryDeriveVendorAuthSecretForUnsecuredPrimaryUser(userId);
                 }
             }
         });
     }
 
-    private void tryDeriveAuthTokenForUnsecuredPrimaryUser(@UserIdInt int userId) {
+    private void tryDeriveVendorAuthSecretForUnsecuredPrimaryUser(@UserIdInt int userId) {
         synchronized (mSpManager) {
-            // Make sure the user has a synthetic password to derive
+            // If there is no SP, then there is no vendor auth secret.
             if (!isSyntheticPasswordBasedCredentialLocked(userId)) {
                 return;
             }
 
-            final long handle = getSyntheticPasswordHandleLocked(userId);
+            final long protectorId = getCurrentLskfBasedProtectorId(userId);
             AuthenticationResult result =
-                    mSpManager.unwrapPasswordBasedSyntheticPassword(getGateKeeperService(),
-                            handle, LockscreenCredential.createNone(), userId, null);
-            if (result.authToken != null) {
-                Slog.i(TAG, "Retrieved auth token for user " + userId);
-                onAuthTokenKnownForUser(userId, result.authToken);
+                    mSpManager.unlockLskfBasedProtector(getGateKeeperService(), protectorId,
+                            LockscreenCredential.createNone(), userId, null);
+            if (result.syntheticPassword != null) {
+                Slog.i(TAG, "Unwrapped SP for unsecured primary user " + userId);
+                onSyntheticPasswordKnown(userId, result.syntheticPassword);
             } else {
-                Slog.e(TAG, "Auth token not available for user " + userId);
+                Slog.e(TAG, "Failed to unwrap SP for unsecured primary user " + userId);
             }
         }
     }
@@ -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) {
@@ -1049,7 +912,7 @@
                                 DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userInfo.id);
 
                         mSpManager.migrateFrpPasswordLocked(
-                                getSyntheticPasswordHandleLocked(userInfo.id),
+                                getCurrentLskfBasedProtectorId(userInfo.id),
                                 userInfo,
                                 redactActualQualityToMostLenientEquivalentQuality(actualQuality));
                     }
@@ -1305,8 +1168,8 @@
         }
         synchronized (mSpManager) {
             if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                final long handle = getSyntheticPasswordHandleLocked(userId);
-                int rawType = mSpManager.getCredentialType(handle, userId);
+                final long protectorId = getCurrentLskfBasedProtectorId(userId);
+                int rawType = mSpManager.getCredentialType(protectorId, userId);
                 if (rawType != CREDENTIAL_TYPE_PASSWORD_OR_PIN) {
                     return rawType;
                 }
@@ -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);
         }
     }
 
@@ -1738,13 +1604,13 @@
                     Slog.e(TAG, "Failed to decrypt child profile key", e);
                 }
             }
-            final long origHandle = getSyntheticPasswordHandleLocked(userId);
-            AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
-                    getGateKeeperService(), origHandle, savedCredential, userId, null);
+            final long oldProtectorId = getCurrentLskfBasedProtectorId(userId);
+            AuthenticationResult authResult = mSpManager.unlockLskfBasedProtector(
+                    getGateKeeperService(), oldProtectorId, savedCredential, userId, null);
             VerifyCredentialResponse response = authResult.gkResponse;
-            AuthenticationToken auth = authResult.authToken;
+            SyntheticPassword sp = authResult.syntheticPassword;
 
-            if (auth == null) {
+            if (sp == null) {
                 if (response == null
                         || response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR) {
                     Slog.w(TAG, "Failed to enroll: incorrect credential.");
@@ -1758,9 +1624,9 @@
                 throw new IllegalStateException("password change failed");
             }
 
-            onAuthTokenKnownForUser(userId, auth);
-            setLockCredentialWithAuthTokenLocked(credential, auth, userId);
-            mSpManager.destroyPasswordBasedSyntheticPassword(origHandle, userId);
+            onSyntheticPasswordKnown(userId, sp);
+            setLockCredentialWithSpLocked(credential, sp, userId);
+            mSpManager.destroyLskfBasedProtector(oldProtectorId, userId);
             sendCredentialsOnChangeIfRequired(credential, userId, isLockTiedToParent);
             return true;
         }
@@ -1966,9 +1832,9 @@
                     Slog.w(TAG, "Escrow token is disabled on the current user");
                     return false;
                 }
-                AuthenticationResult authResult = mSpManager.unwrapWeakTokenBasedSyntheticPassword(
+                AuthenticationResult authResult = mSpManager.unlockWeakTokenBasedProtector(
                         getGateKeeperService(), handle, token, userId);
-                if (authResult.authToken == null) {
+                if (authResult.syntheticPassword == null) {
                     Slog.w(TAG, "Invalid escrow token supplied");
                     return false;
                 }
@@ -2063,7 +1929,7 @@
         }
     }
 
-    /** Unlock disk encryption */
+    /** Unlock file-based encryption */
     private void unlockUserKey(int userId, byte[] secret) {
         final UserInfo userInfo = mUserManager.getUserInfo(userId);
         try {
@@ -2246,20 +2112,20 @@
                         progressCallback);
             }
 
-            long handle = getSyntheticPasswordHandleLocked(userId);
-            authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
-                    getGateKeeperService(), handle, credential, userId, progressCallback);
+            long protectorId = getCurrentLskfBasedProtectorId(userId);
+            authResult = mSpManager.unlockLskfBasedProtector(
+                    getGateKeeperService(), protectorId, credential, userId, progressCallback);
             response = authResult.gkResponse;
 
             if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
                 // credential has matched
                 mBiometricDeferredQueue.addPendingLockoutResetForUser(userId,
-                        authResult.authToken.deriveGkPassword());
+                        authResult.syntheticPassword.deriveGkPassword());
 
                 // perform verifyChallenge with synthetic password which generates the real GK auth
                 // token and response for the current user
-                response = mSpManager.verifyChallenge(getGateKeeperService(), authResult.authToken,
-                        0L /* challenge */, userId);
+                response = mSpManager.verifyChallenge(getGateKeeperService(),
+                        authResult.syntheticPassword, 0L /* challenge */, userId);
                 if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
                     // This shouldn't really happen: the unwrapping of SP succeeds, but SP doesn't
                     // match the recorded GK password handle.
@@ -2269,11 +2135,11 @@
             }
         }
         if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-            onCredentialVerified(authResult.authToken,
+            onCredentialVerified(authResult.syntheticPassword,
                     PasswordMetrics.computeForCredential(credential), userId);
             if ((flags & VERIFY_FLAG_REQUEST_GK_PW_HANDLE) != 0) {
                 final long gkHandle = storeGatekeeperPasswordTemporarily(
-                        authResult.authToken.deriveGkPassword());
+                        authResult.syntheticPassword.deriveGkPassword());
                 response = new VerifyCredentialResponse.Builder()
                         .setGatekeeperPasswordHandle(gkHandle)
                         .build();
@@ -2347,9 +2213,9 @@
         }
     }
 
-    private PasswordMetrics loadPasswordMetrics(AuthenticationToken auth, int userHandle) {
+    private PasswordMetrics loadPasswordMetrics(SyntheticPassword sp, int userHandle) {
         synchronized (mSpManager) {
-            return mSpManager.getPasswordMetrics(auth, getSyntheticPasswordHandleLocked(userHandle),
+            return mSpManager.getPasswordMetrics(sp, getCurrentLskfBasedProtectorId(userHandle),
                     userHandle);
         }
     }
@@ -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,
@@ -2641,24 +2489,23 @@
         }
     }
 
-    private void onAuthTokenKnownForUser(@UserIdInt int userId, AuthenticationToken auth) {
+    private void onSyntheticPasswordKnown(@UserIdInt int userId, SyntheticPassword sp) {
         if (mInjector.isGsiRunning()) {
             Slog.w(TAG, "Running in GSI; skipping calls to AuthSecret and RebootEscrow");
             return;
         }
 
-        mRebootEscrowManager.callToRebootEscrowIfNeeded(userId, auth.getVersion(),
-                auth.getSyntheticPassword());
+        mRebootEscrowManager.callToRebootEscrowIfNeeded(userId, sp.getVersion(),
+                sp.getSyntheticPassword());
 
-        callToAuthSecretIfNeeded(userId, auth);
+        callToAuthSecretIfNeeded(userId, sp);
     }
 
-    private void callToAuthSecretIfNeeded(@UserIdInt int userId,
-            AuthenticationToken auth) {
+    private void callToAuthSecretIfNeeded(@UserIdInt int userId, SyntheticPassword sp) {
         // Pass the primary user's auth secret to the HAL
         if (mAuthSecretService != null && mUserManager.getUserInfo(userId).isPrimary()) {
             try {
-                final byte[] rawSecret = auth.deriveVendorAuthSecret();
+                final byte[] rawSecret = sp.deriveVendorAuthSecret();
                 final ArrayList<Byte> secret = new ArrayList<>(rawSecret.length);
                 for (int i = 0; i < rawSecret.length; ++i) {
                     secret.add(rawSecret[i]);
@@ -2671,66 +2518,51 @@
     }
 
     /**
-     * Precondition: vold and keystore unlocked.
+     * Creates the synthetic password (SP) for the given user and protects it with the user's LSKF.
+     * This is called just once in the lifetime of the user: the first time a nonempty LSKF is set,
+     * or when an escrow token is activated on a device with an empty LSKF.
      *
-     * Create new synthetic password, set up synthetic password blob protected by the supplied
-     * user credential, and make the newly-created SP blob active. This is called just once in the
-     * lifetime of the user: the first time that a user credential is set (!credential.isNone()), or
-     * when an escrow token is activated on an unsecured device (credential.isNone()).
-     *
-     * The invariant under a synthetic password is:
-     * 1. If user credential exists, then both vold and keystore and protected with keys derived
-     *     from the synthetic password.
-     * 2. If user credential does not exist, vold and keystore protection are cleared. This is to
-     *     make it consistent with current behaviour. It also allows ActivityManager to call
-     *     unlockUser() with empty secret.
-     * 3. Once a user is migrated to have synthetic password, its value will never change, no matter
-     *     whether the user changes their lockscreen PIN or clear/reset it. When the user clears its
-     *     lockscreen PIN, we still maintain the existing synthetic password in a password blob
-     *     protected by a default PIN.
-     * 4. The user SID is linked with synthetic password, but its cleared/re-created when the user
-     *     clears/re-creates their lockscreen PIN.
+     * Maintains the SP invariants described in {@link SyntheticPasswordManager}.
      */
     @GuardedBy("mSpManager")
     @VisibleForTesting
-    AuthenticationToken initializeSyntheticPasswordLocked(LockscreenCredential credential,
+    SyntheticPassword initializeSyntheticPasswordLocked(LockscreenCredential credential,
             int userId) {
         Slog.i(TAG, "Initialize SyntheticPassword for user: " + userId);
-        Preconditions.checkState(
-                getSyntheticPasswordHandleLocked(userId) == SyntheticPasswordManager.DEFAULT_HANDLE,
+        Preconditions.checkState(getCurrentLskfBasedProtectorId(userId) ==
+                SyntheticPasswordManager.NULL_PROTECTOR_ID,
                 "Cannot reinitialize SP");
 
-        final AuthenticationToken auth = mSpManager.newSyntheticPassword(userId);
-        long handle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
-                credential, auth, userId);
+        final SyntheticPassword sp = mSpManager.newSyntheticPassword(userId);
+        long protectorId = mSpManager.createLskfBasedProtector(getGateKeeperService(), credential,
+                sp, userId);
         if (!credential.isNone()) {
-            mSpManager.newSidForUser(getGateKeeperService(), auth, userId);
-            mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
-            setUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
-            setKeystorePassword(auth.deriveKeyStorePassword(), userId);
+            mSpManager.newSidForUser(getGateKeeperService(), sp, userId);
+            mSpManager.verifyChallenge(getGateKeeperService(), sp, 0L, userId);
+            setUserKeyProtection(userId, sp.deriveFileBasedEncryptionKey());
+            setKeystorePassword(sp.deriveKeyStorePassword(), userId);
         } else {
             clearUserKeyProtection(userId, null);
             setKeystorePassword(null, userId);
             gateKeeperClearSecureUserId(userId);
         }
         fixateNewestUserKeyAuth(userId);
-        setSyntheticPasswordHandleLocked(handle, userId);
-        onAuthTokenKnownForUser(userId, auth);
-        return auth;
+        setCurrentLskfBasedProtectorId(protectorId, userId);
+        onSyntheticPasswordKnown(userId, sp);
+        return sp;
     }
 
     @VisibleForTesting
-    long getSyntheticPasswordHandleLocked(int userId) {
-        return getLong(SYNTHETIC_PASSWORD_HANDLE_KEY,
-                SyntheticPasswordManager.DEFAULT_HANDLE, userId);
+    long getCurrentLskfBasedProtectorId(int userId) {
+        return getLong(CURRENT_LSKF_BASED_PROTECTOR_ID_KEY,
+                SyntheticPasswordManager.NULL_PROTECTOR_ID, userId);
     }
 
-    private void setSyntheticPasswordHandleLocked(long handle, int userId) {
-        final long oldHandle = getSyntheticPasswordHandleLocked(userId);
-        setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, handle, userId);
-        setLong(PREV_SYNTHETIC_PASSWORD_HANDLE_KEY, oldHandle, userId);
-        setLong(SYNTHETIC_PASSWORD_UPDATE_TIME_KEY, System.currentTimeMillis(), userId);
-
+    private void setCurrentLskfBasedProtectorId(long newProtectorId, int userId) {
+        final long oldProtectorId = getCurrentLskfBasedProtectorId(userId);
+        setLong(CURRENT_LSKF_BASED_PROTECTOR_ID_KEY, newProtectorId, userId);
+        setLong(PREV_LSKF_BASED_PROTECTOR_ID_KEY, oldProtectorId, userId);
+        setLong(LSKF_LAST_CHANGED_TIME_KEY, System.currentTimeMillis(), userId);
     }
 
     @VisibleForTesting
@@ -2745,8 +2577,8 @@
             final int type = mStorage.readPersistentDataBlock().type;
             return type == PersistentData.TYPE_SP || type == PersistentData.TYPE_SP_WEAVER;
         }
-        long handle = getSyntheticPasswordHandleLocked(userId);
-        return handle != SyntheticPasswordManager.DEFAULT_HANDLE;
+        long protectorId = getCurrentLskfBasedProtectorId(userId);
+        return protectorId != SyntheticPasswordManager.NULL_PROTECTOR_ID;
     }
 
     /**
@@ -2776,8 +2608,7 @@
         return handle;
     }
 
-    private void onCredentialVerified(AuthenticationToken authToken, PasswordMetrics metrics,
-            int userId) {
+    private void onCredentialVerified(SyntheticPassword sp, PasswordMetrics metrics, int userId) {
 
         if (metrics != null) {
             synchronized (this) {
@@ -2787,21 +2618,21 @@
             Slog.wtf(TAG, "Null metrics after credential verification");
         }
 
-        unlockKeystore(authToken.deriveKeyStorePassword(), userId);
+        unlockKeystore(sp.deriveKeyStorePassword(), userId);
 
         {
-            final byte[] secret = authToken.deriveDiskEncryptionKey();
+            final byte[] secret = sp.deriveFileBasedEncryptionKey();
             unlockUser(userId, secret);
             Arrays.fill(secret, (byte) 0);
         }
-        activateEscrowTokens(authToken, userId);
+        activateEscrowTokens(sp, userId);
 
         if (isProfileWithSeparatedLock(userId)) {
             setDeviceUnlockedForUser(userId);
         }
         mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
 
-        onAuthTokenKnownForUser(userId, authToken);
+        onSyntheticPasswordKnown(userId, sp);
     }
 
     private void setDeviceUnlockedForUser(int userId) {
@@ -2810,67 +2641,58 @@
     }
 
     /**
-     * Change the user's lockscreen password by creating a new SP blob and update the handle, based
-     * on an existing authentication token. Even though a new SP blob is created, the underlying
-     * synthetic password is never changed.
+     * Changes the user's LSKF by creating an LSKF-based protector that uses the new LSKF (which may
+     * be empty) and setting the new protector as the user's current LSKF-based protector.  The old
+     * LSKF-based protector is not destroyed, and the SP itself is not changed.
      *
-     * When clearing credential, we keep the SP unchanged, but clear its password handle so its
-     * SID is gone. We also clear password from (software-based) keystore and vold, which will be
-     * added back when new password is set in future.
+     * Also maintains the invariants described in {@link SyntheticPasswordManager} by
+     * setting/clearing the protection (by the SP) on the user's file-based encryption key and
+     * auth-bound Keystore keys when the LSKF is added/removed, respectively.  If the new LSKF is
+     * nonempty, then the Gatekeeper auth token is also refreshed.
      */
     @GuardedBy("mSpManager")
-    private long setLockCredentialWithAuthTokenLocked(LockscreenCredential credential,
-            AuthenticationToken auth, int userId) {
-        if (DEBUG) Slog.d(TAG, "setLockCredentialWithAuthTokenLocked: user=" + userId);
+    private long setLockCredentialWithSpLocked(LockscreenCredential credential,
+            SyntheticPassword sp, int userId) {
+        if (DEBUG) Slog.d(TAG, "setLockCredentialWithSpLocked: user=" + userId);
         final int savedCredentialType = getCredentialTypeInternal(userId);
-        long newHandle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
-                credential, auth, userId);
+        final long newProtectorId = mSpManager.createLskfBasedProtector(getGateKeeperService(),
+                credential, sp, userId);
         final Map<Integer, LockscreenCredential> profilePasswords;
         if (!credential.isNone()) {
             // not needed by synchronizeUnifiedWorkChallengeForProfiles()
             profilePasswords = null;
 
             if (mSpManager.hasSidForUser(userId)) {
-                // We are changing password of a secured device, nothing more needed as
-                // createPasswordBasedSyntheticPassword has already taken care of maintaining
-                // the password handle and SID unchanged.
-
-                //refresh auth token
-                mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
+                mSpManager.verifyChallenge(getGateKeeperService(), sp, 0L, userId);
             } else {
-                // A new password is set on a previously-unsecured device, we need to generate
-                // a new SID, and re-add keys to vold and keystore.
-                mSpManager.newSidForUser(getGateKeeperService(), auth, userId);
-                mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
-                setUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
+                mSpManager.newSidForUser(getGateKeeperService(), sp, userId);
+                mSpManager.verifyChallenge(getGateKeeperService(), sp, 0L, userId);
+                setUserKeyProtection(userId, sp.deriveFileBasedEncryptionKey());
                 fixateNewestUserKeyAuth(userId);
-                setKeystorePassword(auth.deriveKeyStorePassword(), userId);
+                setKeystorePassword(sp.deriveKeyStorePassword(), userId);
             }
         } else {
             // Cache all profile password if they use unified work challenge. This will later be
             // used to clear the profile's password in synchronizeUnifiedWorkChallengeForProfiles()
             profilePasswords = getDecryptedPasswordsForAllTiedProfiles(userId);
 
-            // we are clearing password of a secured device, so need to nuke SID as well.
             mSpManager.clearSidForUser(userId);
             gateKeeperClearSecureUserId(userId);
-            // Clear key from vold so ActivityManager can just unlock the user with empty secret
-            // during boot. Vold storage needs to be unlocked before manipulation of the keys can
-            // succeed.
-            unlockUserKey(userId, auth.deriveDiskEncryptionKey());
-            clearUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
+            unlockUserKey(userId, sp.deriveFileBasedEncryptionKey());
+            clearUserKeyProtection(userId, sp.deriveFileBasedEncryptionKey());
             fixateNewestUserKeyAuth(userId);
-            unlockKeystore(auth.deriveKeyStorePassword(), userId);
+            unlockKeystore(sp.deriveKeyStorePassword(), userId);
             setKeystorePassword(null, userId);
             removeBiometricsForUser(userId);
         }
-        setSyntheticPasswordHandleLocked(newHandle, userId);
+        setCurrentLskfBasedProtectorId(newProtectorId, userId);
+        LockPatternUtils.invalidateCredentialTypeCache();
         synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords);
 
         setUserPasswordMetrics(credential, userId);
         mManagedProfilePasswordCache.removePassword(userId);
         if (savedCredentialType != CREDENTIAL_TYPE_NONE) {
-            mSpManager.destroyAllWeakTokenBasedSyntheticPasswords(userId);
+            mSpManager.destroyAllWeakTokenBasedProtectors(userId);
         }
 
         if (profilePasswords != null) {
@@ -2879,7 +2701,7 @@
             }
         }
 
-        return newHandle;
+        return newProtectorId;
     }
 
     private void removeBiometricsForUser(int userId) {
@@ -2976,14 +2798,14 @@
                     Slog.w(TAG, "Synthetic password not enabled");
                     return null;
                 }
-                long handle = getSyntheticPasswordHandleLocked(userId);
-                AuthenticationResult auth = mSpManager.unwrapPasswordBasedSyntheticPassword(
-                        getGateKeeperService(), handle, currentCredential, userId, null);
-                if (auth.authToken == null) {
+                long protectorId = getCurrentLskfBasedProtectorId(userId);
+                AuthenticationResult auth = mSpManager.unlockLskfBasedProtector(
+                        getGateKeeperService(), protectorId, currentCredential, userId, null);
+                if (auth.syntheticPassword == null) {
                     Slog.w(TAG, "Current credential is incorrect");
                     return null;
                 }
-                return auth.authToken.derivePasswordHashFactor();
+                return auth.syntheticPassword.derivePasswordHashFactor();
             }
         } finally {
             scheduleGc();
@@ -2994,46 +2816,47 @@
             @NonNull EscrowTokenStateChangeCallback callback) {
         if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId + ", type=" + type);
         synchronized (mSpManager) {
-            // Migrate to synthetic password based credentials if the user has no password,
-            // the token can then be activated immediately.
-            AuthenticationToken auth = null;
+            // If the user has no LSKF, then the token can be activated immediately, after creating
+            // the user's SP if it doesn't already exist.  Otherwise, the token can't be activated
+            // until the SP is unlocked by another protector (normally the LSKF-based one).
+            SyntheticPassword sp = null;
             if (!isUserSecure(userId)) {
-                long handle = getSyntheticPasswordHandleLocked(userId);
-                if (handle == SyntheticPasswordManager.DEFAULT_HANDLE) {
-                    auth = initializeSyntheticPasswordLocked(LockscreenCredential.createNone(),
+                long protectorId = getCurrentLskfBasedProtectorId(userId);
+                if (protectorId == SyntheticPasswordManager.NULL_PROTECTOR_ID) {
+                    sp = initializeSyntheticPasswordLocked(LockscreenCredential.createNone(),
                             userId);
                 } else {
-                    auth = mSpManager.unwrapPasswordBasedSyntheticPassword(getGateKeeperService(),
-                            handle, LockscreenCredential.createNone(), userId, null).authToken;
+                    sp = mSpManager.unlockLskfBasedProtector(getGateKeeperService(), protectorId,
+                            LockscreenCredential.createNone(), userId, null).syntheticPassword;
                 }
             }
             disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
             if (!mSpManager.hasEscrowData(userId)) {
                 throw new SecurityException("Escrow token is disabled on the current user");
             }
-            long handle = mSpManager.createTokenBasedSyntheticPassword(token, type, userId,
-                    callback);
-            if (auth != null) {
-                mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
+            long handle = mSpManager.addPendingToken(token, type, userId, callback);
+            if (sp != null) {
+                // Activate the token immediately
+                mSpManager.createTokenBasedProtector(handle, sp, userId);
             }
             return handle;
         }
     }
 
-    private void activateEscrowTokens(AuthenticationToken auth, int userId) {
+    private void activateEscrowTokens(SyntheticPassword sp, int userId) {
         if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId);
         synchronized (mSpManager) {
             disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
             for (long handle : mSpManager.getPendingTokensForUser(userId)) {
                 Slog.i(TAG, String.format("activateEscrowTokens: %x %d ", handle, userId));
-                mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
+                mSpManager.createTokenBasedProtector(handle, sp, userId);
             }
         }
     }
 
     private boolean isEscrowTokenActive(long handle, int userId) {
         synchronized (mSpManager) {
-            return mSpManager.existsHandle(handle, userId);
+            return mSpManager.protectorExists(handle, userId);
         }
     }
 
@@ -3047,15 +2870,15 @@
 
     private boolean removeEscrowToken(long handle, int userId) {
         synchronized (mSpManager) {
-            if (handle == getSyntheticPasswordHandleLocked(userId)) {
-                Slog.w(TAG, "Cannot remove password handle");
+            if (handle == getCurrentLskfBasedProtectorId(userId)) {
+                Slog.w(TAG, "Escrow token handle equals LSKF-based protector ID");
                 return false;
             }
             if (mSpManager.removePendingToken(handle, userId)) {
                 return true;
             }
-            if (mSpManager.existsHandle(handle, userId)) {
-                mSpManager.destroyTokenBasedSyntheticPassword(handle, userId);
+            if (mSpManager.protectorExists(handle, userId)) {
+                mSpManager.destroyTokenBasedProtector(handle, userId);
                 return true;
             } else {
                 return false;
@@ -3097,23 +2920,23 @@
     private boolean setLockCredentialWithTokenInternalLocked(LockscreenCredential credential,
             long tokenHandle, byte[] token, int userId) {
         final AuthenticationResult result;
-        result = mSpManager.unwrapTokenBasedSyntheticPassword(getGateKeeperService(), tokenHandle,
-                token, userId);
-        if (result.authToken == null) {
+        result = mSpManager.unlockTokenBasedProtector(getGateKeeperService(), tokenHandle, token,
+                    userId);
+        if (result.syntheticPassword == null) {
             Slog.w(TAG, "Invalid escrow token supplied");
             return false;
         }
         if (result.gkResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
             // Most likely, an untrusted credential reset happened in the past which
             // changed the synthetic password
-            Slog.e(TAG, "Obsolete token: synthetic password derived but it fails GK "
+            Slog.e(TAG, "Obsolete token: synthetic password decrypted but it fails GK "
                     + "verification.");
             return false;
         }
-        onAuthTokenKnownForUser(userId, result.authToken);
-        long oldHandle = getSyntheticPasswordHandleLocked(userId);
-        setLockCredentialWithAuthTokenLocked(credential, result.authToken, userId);
-        mSpManager.destroyPasswordBasedSyntheticPassword(oldHandle, userId);
+        onSyntheticPasswordKnown(userId, result.syntheticPassword);
+        final long oldProtectorId = getCurrentLskfBasedProtectorId(userId);
+        setLockCredentialWithSpLocked(credential, result.syntheticPassword, userId);
+        mSpManager.destroyLskfBasedProtector(oldProtectorId, userId);
         return true;
     }
 
@@ -3124,16 +2947,16 @@
                 Slog.w(TAG, "Escrow token is disabled on the current user");
                 return false;
             }
-            authResult = mSpManager.unwrapTokenBasedSyntheticPassword(getGateKeeperService(),
-                    tokenHandle, token, userId);
-            if (authResult.authToken == null) {
+            authResult = mSpManager.unlockTokenBasedProtector(getGateKeeperService(), tokenHandle,
+                    token, userId);
+            if (authResult.syntheticPassword == null) {
                 Slog.w(TAG, "Invalid escrow token supplied");
                 return false;
             }
         }
 
-        onCredentialVerified(authResult.authToken,
-                loadPasswordMetrics(authResult.authToken, userId), userId);
+        onCredentialVerified(authResult.syntheticPassword,
+                loadPasswordMetrics(authResult.syntheticPassword, userId), userId);
         return true;
     }
 
@@ -3188,11 +3011,11 @@
             pw.println("User " + userId);
             pw.increaseIndent();
             synchronized (mSpManager) {
-                pw.println(String.format("SP Handle: %x",
-                        getSyntheticPasswordHandleLocked(userId)));
-                pw.println(String.format("Last changed: %s (%x)",
-                        timestampToString(getLong(SYNTHETIC_PASSWORD_UPDATE_TIME_KEY, 0, userId)),
-                        getLong(PREV_SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId)));
+                pw.println(String.format("LSKF-based SP protector ID: %x",
+                        getCurrentLskfBasedProtectorId(userId)));
+                pw.println(String.format("LSKF last changed: %s (previous protector: %x)",
+                        timestampToString(getLong(LSKF_LAST_CHANGED_TIME_KEY, 0, userId)),
+                        getLong(PREV_LSKF_BASED_PROTECTOR_ID_KEY, 0, userId)));
             }
             try {
                 pw.println(String.format("SID: %x",
@@ -3491,14 +3314,15 @@
         }
 
         @Override
-        public void onRebootEscrowRestored(byte spVersion, byte[] syntheticPassword, int userId) {
-            SyntheticPasswordManager.AuthenticationToken
-                    authToken = new SyntheticPasswordManager.AuthenticationToken(spVersion);
-            authToken.recreateDirectly(syntheticPassword);
+        public void onRebootEscrowRestored(byte spVersion, byte[] rawSyntheticPassword,
+                int userId) {
+            SyntheticPasswordManager.SyntheticPassword
+                    sp = new SyntheticPasswordManager.SyntheticPassword(spVersion);
+            sp.recreateDirectly(rawSyntheticPassword);
             synchronized (mSpManager) {
-                mSpManager.verifyChallenge(getGateKeeperService(), authToken, 0L, userId);
+                mSpManager.verifyChallenge(getGateKeeperService(), sp, 0L, userId);
             }
-            onCredentialVerified(authToken, loadPasswordMetrics(authToken, userId), userId);
+            onCredentialVerified(sp, loadPasswordMetrics(sp, userId), 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 8161503..e5b50362 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
@@ -230,7 +192,6 @@
         } finally {
             db.endTransaction();
         }
-        dispatchChange(this);
     }
 
     public void prefetchUser(int userId) {
@@ -259,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) {
@@ -297,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
@@ -337,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) {
@@ -352,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 {
@@ -380,86 +333,77 @@
                     }
                 }
             }
-            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) {
+    public void writeSyntheticPasswordState(int userId, long protectorId, String name,
+            byte[] data) {
         ensureSyntheticPasswordDirectoryForUser(userId);
-        writeFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name), data);
+        writeFile(getSyntheticPasswordStateFileForUser(userId, protectorId, name), data);
     }
 
-    public byte[] readSyntheticPasswordState(int userId, long handle, String name) {
-        return readFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name));
+    public byte[] readSyntheticPasswordState(int userId, long protectorId, String name) {
+        return readFile(getSyntheticPasswordStateFileForUser(userId, protectorId, 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);
-        }
+    public void deleteSyntheticPasswordState(int userId, long protectorId, String name) {
+        deleteFile(getSyntheticPasswordStateFileForUser(userId, protectorId, name));
     }
 
-    public Map<Integer, List<Long>> listSyntheticPasswordHandlesForAllUsers(String stateName) {
+    public Map<Integer, List<Long>> listSyntheticPasswordProtectorsForAllUsers(String stateName) {
         Map<Integer, List<Long>> result = new ArrayMap<>();
         final UserManager um = UserManager.get(mContext);
         for (UserInfo user : um.getUsers()) {
-            result.put(user.id, listSyntheticPasswordHandlesForUser(stateName, user.id));
+            result.put(user.id, listSyntheticPasswordProtectorsForUser(stateName, user.id));
         }
         return result;
     }
 
-    public List<Long> listSyntheticPasswordHandlesForUser(String stateName, int userId) {
+    public List<Long> listSyntheticPasswordProtectorsForUser(String stateName, int userId) {
         File baseDir = getSyntheticPasswordDirectoryForUser(userId);
         List<Long> result = new ArrayList<>();
         File[] files = baseDir.listFiles();
@@ -472,7 +416,7 @@
                 try {
                     result.add(Long.parseUnsignedLong(parts[0], 16));
                 } catch (NumberFormatException e) {
-                    Slog.e(TAG, "Failed to parse handle " + parts[0]);
+                    Slog.e(TAG, "Failed to parse protector ID " + parts[0]);
                 }
             }
         }
@@ -481,7 +425,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 */
@@ -492,12 +436,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 protectorId, String name) {
+        String fileName = formatSimple("%016x.%s", protectorId, name);
+        return new File(getSyntheticPasswordDirectoryForUser(userId), fileName);
     }
 
     public void removeUser(int userId) {
@@ -523,11 +464,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) {
@@ -606,7 +546,6 @@
         }
         persistentDataBlock.setFrpCredentialHandle(PersistentData.toBytes(
                 persistentType, userId, qualityForUi, payload));
-        dispatchChange(this);
     }
 
     public PersistentData readPersistentDataBlock() {
@@ -704,7 +643,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) {
@@ -817,20 +756,21 @@
             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) {
@@ -888,10 +828,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/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
index c8f1cb2..371ef76 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
@@ -52,7 +52,7 @@
     private static final int PROFILE_KEY_IV_SIZE = 12;
     private static final int DEFAULT_TAG_LENGTH_BITS = 128;
     private static final int AES_KEY_LENGTH = 32; // 256-bit AES key
-    private static final byte[] APPLICATION_ID_PERSONALIZATION = "application-id".getBytes();
+    private static final byte[] PROTECTOR_SECRET_PERSONALIZATION = "application-id".getBytes();
     // Time between the user credential is verified with GK and the decryption of synthetic password
     // under the auth-bound key. This should always happen one after the other, but give it 15
     // seconds just to be sure.
@@ -127,15 +127,19 @@
         }
     }
 
-    public static byte[] decryptBlobV1(String keyAlias, byte[] blob, byte[] applicationId) {
+    /**
+     * Decrypt a legacy SP blob which did the Keystore and software encryption layers in the wrong
+     * order.
+     */
+    public static byte[] decryptBlobV1(String keyAlias, byte[] blob, byte[] protectorSecret) {
         try {
             KeyStore keyStore = getKeyStore();
-            SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null);
-            if (decryptionKey == null) {
+            SecretKey keyStoreKey = (SecretKey) keyStore.getKey(keyAlias, null);
+            if (keyStoreKey == null) {
                 throw new IllegalStateException("SP key is missing: " + keyAlias);
             }
-            byte[] intermediate = decrypt(applicationId, APPLICATION_ID_PERSONALIZATION, blob);
-            return decrypt(decryptionKey, intermediate);
+            byte[] intermediate = decrypt(protectorSecret, PROTECTOR_SECRET_PERSONALIZATION, blob);
+            return decrypt(keyStoreKey, intermediate);
         } catch (Exception e) {
             Slog.e(TAG, "Failed to decrypt V1 blob", e);
             throw new IllegalStateException("Failed to decrypt blob", e);
@@ -157,16 +161,19 @@
         return keyStore;
     }
 
-    public static byte[] decryptBlob(String keyAlias, byte[] blob, byte[] applicationId) {
+    /**
+     * Decrypts an SP blob that was created by {@link #createBlob}.
+     */
+    public static byte[] decryptBlob(String keyAlias, byte[] blob, byte[] protectorSecret) {
         try {
             final KeyStore keyStore = getKeyStore();
 
-            SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null);
-            if (decryptionKey == null) {
+            SecretKey keyStoreKey = (SecretKey) keyStore.getKey(keyAlias, null);
+            if (keyStoreKey == null) {
                 throw new IllegalStateException("SP key is missing: " + keyAlias);
             }
-            byte[] intermediate = decrypt(decryptionKey, blob);
-            return decrypt(applicationId, APPLICATION_ID_PERSONALIZATION, intermediate);
+            byte[] intermediate = decrypt(keyStoreKey, blob);
+            return decrypt(protectorSecret, PROTECTOR_SECRET_PERSONALIZATION, intermediate);
         } catch (CertificateException | IOException | BadPaddingException
                 | IllegalBlockSizeException
                 | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
@@ -177,11 +184,22 @@
         }
     }
 
-    public static byte[] createBlob(String keyAlias, byte[] data, byte[] applicationId, long sid) {
+    /**
+     * Creates a new SP blob by encrypting the given data.  Two encryption layers are applied: an
+     * inner layer using a hash of protectorSecret as the key, and an outer layer using a new
+     * Keystore key with the given alias and optionally bound to a SID.
+     *
+     * The reason we use a layer of software encryption, instead of using protectorSecret as the
+     * applicationId of the Keystore key, is to work around buggy KeyMint implementations that don't
+     * cryptographically bind the applicationId to the key.  The Keystore layer has to be the outer
+     * layer, so that LSKF verification is ratelimited by Gatekeeper when Weaver is unavailable.
+     */
+    public static byte[] createBlob(String keyAlias, byte[] data, byte[] protectorSecret,
+            long sid) {
         try {
             KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
             keyGenerator.init(AES_KEY_LENGTH * 8, new SecureRandom());
-            SecretKey secretKey = keyGenerator.generateKey();
+            SecretKey keyStoreKey = keyGenerator.generateKey();
             final KeyStore keyStore = getKeyStore();
             KeyProtection.Builder builder = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
                     .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
@@ -194,10 +212,10 @@
             }
 
             keyStore.setEntry(keyAlias,
-                    new KeyStore.SecretKeyEntry(secretKey),
+                    new KeyStore.SecretKeyEntry(keyStoreKey),
                     builder.build());
-            byte[] intermediate = encrypt(applicationId, APPLICATION_ID_PERSONALIZATION, data);
-            return encrypt(secretKey, intermediate);
+            byte[] intermediate = encrypt(protectorSecret, PROTECTOR_SECRET_PERSONALIZATION, data);
+            return encrypt(keyStoreKey, intermediate);
         } catch (CertificateException | IOException | BadPaddingException
                 | IllegalBlockSizeException
                 | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index f5151c4..2d0143a 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -68,32 +68,42 @@
 
 
 /**
- * A class that maintains the wrapping of synthetic password by user credentials or escrow tokens.
- * It's (mostly) a pure storage for synthetic passwords, providing APIs to creating and destroying
- * synthetic password blobs which are wrapped by user credentials or escrow tokens.
+ * A class that manages a user's synthetic password (SP) ({@link #SyntheticPassword}), along with a
+ * set of SP protectors that are independent ways that the SP is protected.
  *
- * Here is the assumptions it makes:
- *   Each user has one single synthetic password at any time.
- *   The SP has an associated password handle, which binds to the SID for that user. The password
- *   handle is persisted by SyntheticPasswordManager internally.
- *   If the user credential is null, it's treated as if the credential is DEFAULT_PASSWORD
+ * Invariants for SPs:
  *
- * Information persisted on disk:
- *   for each user (stored under DEFAULT_HANDLE):
- *     SP_HANDLE_NAME: GateKeeper password handle of synthetic password. Only available if user
- *                     credential exists, cleared when user clears their credential.
- *     SP_E0_NAME, SP_P1_NAME: Secret to derive synthetic password when combined with escrow
- *                     tokens. Destroyed when escrow support is turned off for the given user.
+ *  - A user's SP never changes, but SP protectors can be added and removed.  There is always a
+ *    protector that protects the SP with the user's Lock Screen Knowledge Factor (LSKF), a.k.a.
+ *    LockscreenCredential.  The LSKF may be empty (none).  There may be escrow token-based
+ *    protectors as well, only for specific use cases such as enterprise-managed users.
  *
- *     for each SP blob under the user (stored under the corresponding handle):
- *       SP_BLOB_NAME: The encrypted synthetic password. Always exists.
- *       PASSWORD_DATA_NAME: Metadata about user credential. Only exists for password based SP.
- *       SECDISCARDABLE_NAME: Part of the necessary ingredient to decrypt SP_BLOB_NAME for the
- *                            purpose of secure deletion. Exists if this is a non-weaver SP
- *                            (both password and token based), or it's a token-based SP under weaver.
- *       WEAVER_SLOT: Metadata about the weaver slot used. Only exists if this is a SP under weaver.
+ *  - While the user's LSKF is nonempty, the SP protects the user's CE (credential encrypted)
+ *    storage and auth-bound Keystore keys: the user's CE key is encrypted by an SP-derived secret,
+ *    and the user's Keystore and Gatekeeper passwords are other SP-derived secrets.  However, while
+ *    the user's LSKF is empty, these protections are cleared; this is needed to invalidate the
+ *    auth-bound keys and make UserController.unlockUser() work with an empty secret.
  *
+ * Files stored on disk for each user:
+ *   For the SP itself, stored under NULL_PROTECTOR_ID:
+ *     SP_HANDLE_NAME: GateKeeper password handle of a password derived from the SP.  Only exists
+ *                     while the LSKF is nonempty.
+ *     SP_E0_NAME, SP_P1_NAME: Information needed to create and use escrow token-based protectors.
+ *                             Deleted when escrow token support is disabled for the user.
  *
+ *     For each protector, stored under the corresponding protector ID:
+ *       SP_BLOB_NAME: The encrypted SP secret (the SP itself or the P0 value).  Always exists.
+ *       PASSWORD_DATA_NAME: Data used for LSKF verification, such as the scrypt salt and
+ *                           parameters.  Only exists for LSKF-based protectors.
+ *       PASSWORD_METRICS_NAME: Metrics about the LSKF, encrypted by a key derived from the SP.
+ *                              Only exists for LSKF-based protectors.
+ *       SECDISCARDABLE_NAME: A large number of random bytes that all need to be known in order to
+ *                            decrypt SP_BLOB_NAME.  When the protector is deleted, this file is
+ *                            overwritten and deleted as a "best-effort" attempt to support secure
+ *                            deletion when hardware support for secure deletion is unavailable.
+ *                            Doesn't exist for LSKF-based protectors that use Weaver.
+ *       WEAVER_SLOT: Contains the Weaver slot number used by this protector.  Only exists if the
+ *                    protector uses Weaver.
  */
 public class SyntheticPasswordManager {
     private static final String SP_BLOB_NAME = "spblob";
@@ -106,18 +116,24 @@
     private static final String WEAVER_SLOT_NAME = "weaver";
     private static final String PASSWORD_METRICS_NAME = "metrics";
 
-    public static final long DEFAULT_HANDLE = 0L;
+    // used for files associated with the SP itself, not with a particular protector
+    public static final long NULL_PROTECTOR_ID = 0L;
+
     private static final byte[] DEFAULT_PASSWORD = "default-password".getBytes();
 
     private static final byte WEAVER_VERSION = 1;
     private static final int INVALID_WEAVER_SLOT = -1;
 
+    // Careful: the SYNTHETIC_PASSWORD_* version numbers are overloaded to identify both the version
+    // of the protector and the version of the synthetic password itself.  All a user's protectors
+    // must use a version that treats the synthetic password itself in a compatible way.
     private static final byte SYNTHETIC_PASSWORD_VERSION_V1 = 1;
     private static final byte SYNTHETIC_PASSWORD_VERSION_V2 = 2;
     private static final byte SYNTHETIC_PASSWORD_VERSION_V3 = 3;
-    private static final byte SYNTHETIC_PASSWORD_PASSWORD_BASED = 0;
-    private static final byte SYNTHETIC_PASSWORD_STRONG_TOKEN_BASED = 1;
-    private static final byte SYNTHETIC_PASSWORD_WEAK_TOKEN_BASED = 2;
+
+    private static final byte PROTECTOR_TYPE_LSKF_BASED = 0;
+    private static final byte PROTECTOR_TYPE_STRONG_TOKEN_BASED = 1;
+    private static final byte PROTECTOR_TYPE_WEAK_TOKEN_BASED = 2;
 
     // 256-bit synthetic password
     private static final byte SYNTHETIC_PASSWORD_LENGTH = 256 / 8;
@@ -147,7 +163,7 @@
 
     static class AuthenticationResult {
         // Non-null if password/token passes verification, null otherwise
-        @Nullable public AuthenticationToken authToken;
+        @Nullable public SyntheticPassword syntheticPassword;
         // OK:    password / token passes verification, user has a lockscreen
         // null:  user does not have a lockscreen (but password / token passes verification)
         // ERROR: password / token fails verification
@@ -156,39 +172,34 @@
     }
 
     /**
-     * This class represents the main cryptographic secret for a given user (a.k.a synthietic
-     * password). This secret is derived from the user's lockscreen credential or password escrow
-     * token. All other cryptograhic keys related to the user, including disk encryption key,
-     * keystore encryption key, gatekeeper auth key, vendor auth secret and others are directly
-     * derived from this token.
-     * <p>
-     * The main secret associated with an authentication token is retrievable from
-     * {@link AuthenticationToken#getSyntheticPassword()} and the authentication token can be
-     * reconsturcted from the main secret later with
-     * {@link AuthenticationToken#recreateDirectly(byte[])}. The first time an authentication token
-     * is needed, it should be created with {@link AuthenticationToken#create()} so that the
-     * necessary escrow data ({@link #mEncryptedEscrowSplit0} and {@link #mEscrowSplit1}) is
-     * properly initialized. The caller can either persist the (non-secret) esscrow data if escrow
-     * is required, or discard it to cryptograhically disable escrow. To support escrow, the caller
-     * needs to securely store the secret returned from
-     * {@link AuthenticationToken#getEscrowSecret()}, and at the time of use, load the escrow data
-     * back with {@link AuthenticationToken#setEscrowData(byte[], byte[])} and then re-create the
-     * main secret from the escrow secret via
-     * {@link AuthenticationToken#recreateFromEscrow(byte[])}.
+     * A synthetic password (SP) is the main cryptographic secret for a user.  The SP is used only
+     * as input to a Key Derivation Function (KDF) to derive other keys.
+     *
+     * SPs are created by {@link SyntheticPassword#create()} as the hash of two random values P0 and
+     * P1.  E0 (P0 encrypted by an SP-derived key) and P1 can then be stored on-disk.  This approach
+     * is used instead of direct random generation of the SP so that escrow token-based protectors
+     * can protect P0 instead of the SP itself.  This makes it possible to cryptographically disable
+     * the ability to create and use such protectors by deleting (or never storing) E0 and P1.
+     *
+     * When protecting the SP directly, use {@link SyntheticPassword#getSyntheticPassword()} to get
+     * the raw SP, and later {@link SyntheticPassword#recreateDirectly(byte[])} to re-create the SP.
+     * When protecting P0, use {@link SyntheticPassword#getEscrowSecret()} to get P0, and later
+     * {@link SyntheticPassword#setEscrowData(byte[], byte[])} followed by
+     * {@link SyntheticPassword#recreateFromEscrow()} to re-create the SP.
      */
-    static class AuthenticationToken {
+    static class SyntheticPassword {
         private final byte mVersion;
         /**
          * Here is the relationship between these fields:
          * Generate two random block P0 and P1. P1 is recorded in mEscrowSplit1 but P0 is not.
          * mSyntheticPassword = hash(P0 || P1)
-         * E0 = P0 encrypted under syntheticPassword, recoreded in mEncryptedEscrowSplit0.
+         * E0 = P0 encrypted under syntheticPassword, recorded in mEncryptedEscrowSplit0.
          */
         private @NonNull byte[] mSyntheticPassword;
         private @Nullable byte[] mEncryptedEscrowSplit0;
         private @Nullable byte[] mEscrowSplit1;
 
-        AuthenticationToken(byte version) {
+        SyntheticPassword(byte version) {
             mVersion = version;
         }
 
@@ -214,7 +225,7 @@
             return deriveSubkey(PERSONALIZATION_SP_GK_AUTH);
         }
 
-        public byte[] deriveDiskEncryptionKey() {
+        public byte[] deriveFileBasedEncryptionKey() {
             return deriveSubkey(PERSONALIZATION_FBE_KEY);
         }
 
@@ -232,8 +243,8 @@
         }
 
         /**
-         * Assign escrow data to this auth token. This is a prerequisite to call
-         * {@link AuthenticationToken#recreateFromEscrow}.
+         * Assigns escrow data to this synthetic password. This is a prerequisite to call
+         * {@link SyntheticPassword#recreateFromEscrow}.
          */
         public void setEscrowData(@Nullable byte[] encryptedEscrowSplit0,
                 @Nullable byte[] escrowSplit1) {
@@ -242,8 +253,8 @@
         }
 
         /**
-         * Re-creates authentication token from escrow secret (escrowSplit0, returned from
-         * {@link AuthenticationToken#getEscrowSecret}). Escrow data needs to be loaded
+         * Re-creates a synthetic password from the escrow secret (escrowSplit0, returned from
+         * {@link SyntheticPassword#getEscrowSecret}). Escrow data needs to be loaded
          * by {@link #setEscrowData} before calling this.
          */
         public void recreateFromEscrow(byte[] escrowSplit0) {
@@ -253,7 +264,7 @@
         }
 
         /**
-         * Re-creates authentication token from synthetic password directly.
+         * Re-creates a synthetic password from its raw bytes.
          */
         public void recreateDirectly(byte[] syntheticPassword) {
             this.mSyntheticPassword = Arrays.copyOf(syntheticPassword, syntheticPassword.length);
@@ -262,8 +273,8 @@
         /**
          * Generates a new random synthetic password with escrow data.
          */
-        static AuthenticationToken create() {
-            AuthenticationToken result = new AuthenticationToken(SYNTHETIC_PASSWORD_VERSION_V3);
+        static SyntheticPassword create() {
+            SyntheticPassword result = new SyntheticPassword(SYNTHETIC_PASSWORD_VERSION_V3);
             byte[] escrowSplit0 = secureRandom(SYNTHETIC_PASSWORD_LENGTH);
             byte[] escrowSplit1 = secureRandom(SYNTHETIC_PASSWORD_LENGTH);
             result.recreate(escrowSplit0, escrowSplit1);
@@ -275,7 +286,7 @@
 
         /**
          * Re-creates synthetic password from both escrow splits. See javadoc for
-         * AuthenticationToken.mSyntheticPassword for details on what each block means.
+         * SyntheticPassword.mSyntheticPassword for details on what each block means.
          */
         private void recreate(byte[] escrowSplit0, byte[] escrowSplit1) {
             mSyntheticPassword = bytesToHex(SyntheticPasswordCrypto.personalizedHash(
@@ -283,8 +294,8 @@
         }
 
         /**
-         * Returns the escrow secret that can be used later to reconstruct this authentication
-         * token from {@link #recreateFromEscrow(byte[])}. Only possible if escrow is not disabled
+         * Returns the escrow secret that can be used later to reconstruct this synthetic password
+         * from {@link #recreateFromEscrow(byte[])}. Only possible if escrow is not disabled
          * (encryptedEscrowSplit0 known).
          */
         public byte[] getEscrowSecret() {
@@ -296,16 +307,15 @@
         }
 
         /**
-         * Returns the raw synthetic password that can be used later to reconstruct this
-         * authentication token from {@link #recreateDirectly(byte[])}
+         * Returns the raw synthetic password, for later use with {@link #recreateDirectly(byte[])}.
          */
         public byte[] getSyntheticPassword() {
             return mSyntheticPassword;
         }
 
         /**
-         * Returns the version of this AuthenticationToken for use with reconstructing
-         * this with a synthetic password version.
+         * Returns the version number of this synthetic password.  This version number determines
+         * the algorithm used to derive subkeys.
          */
         public byte getVersion() {
             return mVersion;
@@ -318,8 +328,8 @@
         byte scryptLogP;
         public int credentialType;
         byte[] salt;
-        // For GateKeeper-based credential, this is the password handle returned by GK,
-        // for weaver-based credential, this is empty.
+        // If Weaver is available, then this field is empty.  Otherwise, it is the Gatekeeper
+        // password handle that resulted from enrolling the hashed LSKF.
         public byte[] passwordHandle;
 
         public static PasswordData create(int passwordType) {
@@ -377,13 +387,14 @@
 
     static class SyntheticPasswordBlob {
         byte mVersion;
-        byte mType;
+        byte mProtectorType;
         byte[] mContent;
 
-        public static SyntheticPasswordBlob create(byte version, byte type, byte[] content) {
+        public static SyntheticPasswordBlob create(byte version, byte protectorType,
+                byte[] content) {
             SyntheticPasswordBlob result = new SyntheticPasswordBlob();
             result.mVersion = version;
-            result.mType = type;
+            result.mProtectorType = protectorType;
             result.mContent = content;
             return result;
         }
@@ -391,7 +402,7 @@
         public static SyntheticPasswordBlob fromBytes(byte[] data) {
             SyntheticPasswordBlob result = new SyntheticPasswordBlob();
             result.mVersion = data[0];
-            result.mType = data[1];
+            result.mProtectorType = data[1];
             result.mContent = Arrays.copyOfRange(data, 2, data.length);
             return result;
         }
@@ -399,7 +410,7 @@
         public byte[] toByte() {
             byte[] blob = new byte[mContent.length + 1 + 1];
             blob[0] = mVersion;
-            blob[1] = mType;
+            blob[1] = mProtectorType;
             System.arraycopy(mContent, 0, blob, 2, mContent.length);
             return blob;
         }
@@ -569,9 +580,10 @@
     }
 
     public void removeUser(IGateKeeperService gatekeeper, int userId) {
-        for (long handle : mStorage.listSyntheticPasswordHandlesForUser(SP_BLOB_NAME, userId)) {
-            destroyWeaverSlot(handle, userId);
-            destroySPBlobKey(getKeyName(handle));
+        for (long protectorId : mStorage.listSyntheticPasswordProtectorsForUser(SP_BLOB_NAME,
+                    userId)) {
+            destroyWeaverSlot(protectorId, userId);
+            destroySPBlobKey(getKeyName(protectorId));
         }
         // Remove potential persistent state (in RPMB), to prevent them from accumulating and
         // causing problems.
@@ -582,8 +594,8 @@
         }
     }
 
-    int getCredentialType(long handle, int userId) {
-        byte[] passwordData = loadState(PASSWORD_DATA_NAME, handle, userId);
+    int getCredentialType(long protectorId, int userId) {
+        byte[] passwordData = loadState(PASSWORD_DATA_NAME, protectorId, userId);
         if (passwordData == null) {
             Slog.w(TAG, "getCredentialType: encountered empty password data for user " + userId);
             return LockPatternUtils.CREDENTIAL_TYPE_NONE;
@@ -599,9 +611,7 @@
     }
 
     /**
-     * Initializes a new Authentication token for the given user.
-     *
-     * The authentication token will bear a randomly-generated synthetic password.
+     * Creates a new synthetic password (SP) for the given user.
      *
      * Any existing SID for the user is cleared.
      *
@@ -609,22 +619,21 @@
      * an escrow scheme. This information can be removed with {@link #destroyEscrowData} if
      * password escrow should be disabled completely on the given user.
      */
-    AuthenticationToken newSyntheticPassword(int userId) {
+    SyntheticPassword newSyntheticPassword(int userId) {
         clearSidForUser(userId);
-        AuthenticationToken result = AuthenticationToken.create();
+        SyntheticPassword result = SyntheticPassword.create();
         saveEscrowData(result, userId);
         return result;
     }
 
     /**
      * Enroll a new password handle and SID for the given synthetic password and persist it on disk.
-     * Used when adding password to previously-unsecured devices.
+     * Used when the LSKF is changed from empty to nonempty.
      */
-    public void newSidForUser(IGateKeeperService gatekeeper, AuthenticationToken authToken,
-            int userId) {
+    public void newSidForUser(IGateKeeperService gatekeeper, SyntheticPassword sp, int userId) {
         GateKeeperResponse response;
         try {
-            response = gatekeeper.enroll(userId, null, null, authToken.deriveGkPassword());
+            response = gatekeeper.enroll(userId, null, null, sp.deriveGkPassword());
         } catch (RemoteException e) {
             throw new IllegalStateException("Failed to create new SID for user", e);
         }
@@ -637,49 +646,48 @@
 
     // Nuke the SP handle (and as a result, its SID) for the given user.
     public void clearSidForUser(int userId) {
-        destroyState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
+        destroyState(SP_HANDLE_NAME, NULL_PROTECTOR_ID, userId);
     }
 
     public boolean hasSidForUser(int userId) {
-        return hasState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
+        return hasState(SP_HANDLE_NAME, NULL_PROTECTOR_ID, userId);
     }
 
-    // if null, it means there is no SID associated with the user
-    // This can happen if the user is migrated to SP but currently
-    // do not have a lockscreen password.
+    // If this returns null, it means there is no SID associated with the user.  This happens if the
+    // user has an empty LSKF, but does have an SP.
     private byte[] loadSyntheticPasswordHandle(int userId) {
-        return loadState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
+        return loadState(SP_HANDLE_NAME, NULL_PROTECTOR_ID, userId);
     }
 
     private void saveSyntheticPasswordHandle(byte[] spHandle, int userId) {
-        saveState(SP_HANDLE_NAME, spHandle, DEFAULT_HANDLE, userId);
+        saveState(SP_HANDLE_NAME, spHandle, NULL_PROTECTOR_ID, userId);
     }
 
-    private boolean loadEscrowData(AuthenticationToken authToken, int userId) {
-        byte[] e0 = loadState(SP_E0_NAME, DEFAULT_HANDLE, userId);
-        byte[] p1 = loadState(SP_P1_NAME, DEFAULT_HANDLE, userId);
-        authToken.setEscrowData(e0,  p1);
+    private boolean loadEscrowData(SyntheticPassword sp, int userId) {
+        byte[] e0 = loadState(SP_E0_NAME, NULL_PROTECTOR_ID, userId);
+        byte[] p1 = loadState(SP_P1_NAME, NULL_PROTECTOR_ID, userId);
+        sp.setEscrowData(e0,  p1);
         return e0 != null && p1 != null;
     }
 
-    private void saveEscrowData(AuthenticationToken authToken, int userId) {
-        saveState(SP_E0_NAME, authToken.mEncryptedEscrowSplit0, DEFAULT_HANDLE, userId);
-        saveState(SP_P1_NAME, authToken.mEscrowSplit1, DEFAULT_HANDLE, userId);
+    private void saveEscrowData(SyntheticPassword sp, int userId) {
+        saveState(SP_E0_NAME, sp.mEncryptedEscrowSplit0, NULL_PROTECTOR_ID, userId);
+        saveState(SP_P1_NAME, sp.mEscrowSplit1, NULL_PROTECTOR_ID, userId);
     }
 
     public boolean hasEscrowData(int userId) {
-        return hasState(SP_E0_NAME, DEFAULT_HANDLE, userId)
-                && hasState(SP_P1_NAME, DEFAULT_HANDLE, userId);
+        return hasState(SP_E0_NAME, NULL_PROTECTOR_ID, userId)
+                && hasState(SP_P1_NAME, NULL_PROTECTOR_ID, userId);
     }
 
     public void destroyEscrowData(int userId) {
-        destroyState(SP_E0_NAME, DEFAULT_HANDLE, userId);
-        destroyState(SP_P1_NAME, DEFAULT_HANDLE, userId);
+        destroyState(SP_E0_NAME, NULL_PROTECTOR_ID, userId);
+        destroyState(SP_P1_NAME, NULL_PROTECTOR_ID, userId);
     }
 
-    private int loadWeaverSlot(long handle, int userId) {
+    private int loadWeaverSlot(long protectorId, int userId) {
         final int LENGTH = Byte.BYTES + Integer.BYTES;
-        byte[] data = loadState(WEAVER_SLOT_NAME, handle, userId);
+        byte[] data = loadState(WEAVER_SLOT_NAME, protectorId, userId);
         if (data == null || data.length != LENGTH) {
             return INVALID_WEAVER_SLOT;
         }
@@ -687,22 +695,22 @@
         buffer.put(data, 0, data.length);
         buffer.flip();
         if (buffer.get() != WEAVER_VERSION) {
-            Slog.e(TAG, "Invalid weaver slot version of handle " + handle);
+            Slog.e(TAG, "Invalid weaver slot version for protector " + protectorId);
             return INVALID_WEAVER_SLOT;
         }
         return buffer.getInt();
     }
 
-    private void saveWeaverSlot(int slot, long handle, int userId) {
+    private void saveWeaverSlot(int slot, long protectorId, int userId) {
         ByteBuffer buffer = ByteBuffer.allocate(Byte.BYTES + Integer.BYTES);
         buffer.put(WEAVER_VERSION);
         buffer.putInt(slot);
-        saveState(WEAVER_SLOT_NAME, buffer.array(), handle, userId);
+        saveState(WEAVER_SLOT_NAME, buffer.array(), protectorId, userId);
     }
 
-    private void destroyWeaverSlot(long handle, int userId) {
-        int slot = loadWeaverSlot(handle, userId);
-        destroyState(WEAVER_SLOT_NAME, handle, userId);
+    private void destroyWeaverSlot(long protectorId, int userId) {
+        int slot = loadWeaverSlot(protectorId, userId);
+        destroyState(WEAVER_SLOT_NAME, protectorId, userId);
         if (slot != INVALID_WEAVER_SLOT) {
             Set<Integer> usedSlots = getUsedWeaverSlots();
             if (!usedSlots.contains(slot)) {
@@ -726,12 +734,12 @@
      * unintentionally.
      */
     private Set<Integer> getUsedWeaverSlots() {
-        Map<Integer, List<Long>> slotHandles = mStorage.listSyntheticPasswordHandlesForAllUsers(
-                WEAVER_SLOT_NAME);
+        Map<Integer, List<Long>> protectorIds =
+            mStorage.listSyntheticPasswordProtectorsForAllUsers(WEAVER_SLOT_NAME);
         HashSet<Integer> slots = new HashSet<>();
-        for (Map.Entry<Integer, List<Long>> entry : slotHandles.entrySet()) {
-            for (Long handle : entry.getValue()) {
-                int slot = loadWeaverSlot(handle, entry.getKey());
+        for (Map.Entry<Integer, List<Long>> entry : protectorIds.entrySet()) {
+            for (Long protectorId : entry.getValue()) {
+                int slot = loadWeaverSlot(protectorId, entry.getKey());
                 slots.add(slot);
             }
         }
@@ -750,29 +758,24 @@
     }
 
     /**
-     * Create a new password based SP blob based on the supplied authentication token, such that
-     * a future successful authentication with unwrapPasswordBasedSyntheticPassword() would result
-     * in the same authentication token.
+     * Creates a protector that protects the user's SP with the given LSKF (which may be empty).
      *
-     * This method only creates SP blob wrapping around the given synthetic password and does not
-     * handle logic around SID or SP handle. The caller should separately ensure that the user's SID
-     * is consistent with the device state by calling other APIs in this class.
+     * This method only creates a new protector that isn't referenced by anything; it doesn't handle
+     * any higher-level tasks involved in changing the LSKF.
      *
-     * @see #newSidForUser
-     * @see #clearSidForUser
-     * @return a new password handle for the wrapped SP blob
-     * @throw IllegalStateException if creation fails.
+     * @return the ID of the new protector
+     * @throws IllegalStateException on failure
      */
-    public long createPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
-            LockscreenCredential credential, AuthenticationToken authToken, int userId) {
-        long handle = generateHandle();
+    public long createLskfBasedProtector(IGateKeeperService gatekeeper,
+            LockscreenCredential credential, SyntheticPassword sp, int userId) {
+        long protectorId = generateProtectorId();
         PasswordData pwd = PasswordData.create(credential.getType());
         byte[] pwdToken = computePasswordToken(credential, pwd);
         final long sid;
-        final byte[] applicationId;
+        final byte[] protectorSecret;
 
         if (isWeaverAvailable()) {
-            // Weaver based user password
+            // Protector uses Weaver to verify the LSKF
             int weaverSlot = getNextAvailableWeaverSlot();
             Slog.i(TAG, "Weaver enroll password to slot " + weaverSlot + " for user " + userId);
             byte[] weaverSecret = weaverEnroll(weaverSlot, passwordTokenToWeaverKey(pwdToken),
@@ -781,15 +784,17 @@
                 throw new IllegalStateException(
                         "Fail to enroll user password under weaver " + userId);
             }
-            saveWeaverSlot(weaverSlot, handle, userId);
+            saveWeaverSlot(weaverSlot, protectorId, userId);
             mPasswordSlotManager.markSlotInUse(weaverSlot);
             // No need to pass in quality since the credential type already encodes sufficient info
             synchronizeWeaverFrpPassword(pwd, 0, userId, weaverSlot);
 
             pwd.passwordHandle = null;
             sid = GateKeeper.INVALID_SECURE_USER_ID;
-            applicationId = transformUnderWeaverSecret(pwdToken, weaverSecret);
+            protectorSecret = transformUnderWeaverSecret(pwdToken, weaverSecret);
         } else {
+            // Protector uses Gatekeeper to verify the LSKF
+
             // In case GK enrollment leaves persistent state around (in RPMB), this will nuke them
             // to prevent them from accumulating and causing problems.
             try {
@@ -797,30 +802,30 @@
             } catch (RemoteException ignore) {
                 Slog.w(TAG, "Failed to clear SID from gatekeeper");
             }
-            // GateKeeper based user password
             GateKeeperResponse response;
             try {
                 response = gatekeeper.enroll(fakeUid(userId), null, null,
                         passwordTokenToGkInput(pwdToken));
             } catch (RemoteException e) {
-                throw new IllegalStateException("Failed to enroll password for new SP blob", e);
+                throw new IllegalStateException("Failed to enroll LSKF for new SP protector for "
+                        + "user " + userId, e);
             }
             if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
-                throw new IllegalStateException(
-                        "Fail to enroll user password when creating SP for user " + userId);
+                throw new IllegalStateException("Failed to enroll LSKF for new SP protector for "
+                        + "user " + userId);
             }
             pwd.passwordHandle = response.getPayload();
             sid = sidFromPasswordHandle(pwd.passwordHandle);
-            applicationId = transformUnderSecdiscardable(pwdToken,
-                    createSecdiscardable(handle, userId));
+            protectorSecret = transformUnderSecdiscardable(pwdToken,
+                    createSecdiscardable(protectorId, userId));
             // No need to pass in quality since the credential type already encodes sufficient info
             synchronizeFrpPassword(pwd, 0, userId);
         }
-        saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
-        savePasswordMetrics(credential, authToken, handle, userId);
-        createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED, authToken,
-                applicationId, sid, userId);
-        return handle;
+        saveState(PASSWORD_DATA_NAME, pwd.toBytes(), protectorId, userId);
+        savePasswordMetrics(credential, sp, protectorId, userId);
+        createSyntheticPasswordBlob(protectorId, PROTECTOR_TYPE_LSKF_BASED, sp, protectorSecret,
+                sid, userId);
+        return protectorId;
     }
 
     public VerifyCredentialResponse verifyFrpCredential(IGateKeeperService gatekeeper,
@@ -858,13 +863,14 @@
     }
 
 
-    public void migrateFrpPasswordLocked(long handle, UserInfo userInfo, int requestedQuality) {
+    public void migrateFrpPasswordLocked(long protectorId, UserInfo userInfo,
+            int requestedQuality) {
         if (mStorage.getPersistentDataBlockManager() != null
                 && LockPatternUtils.userOwnsFrpCredential(mContext, userInfo)) {
-            PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, handle,
+            PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, protectorId,
                     userInfo.id));
             if (pwd.credentialType != LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-                int weaverSlot = loadWeaverSlot(handle, userInfo.id);
+                int weaverSlot = loadWeaverSlot(protectorId, userInfo.id);
                 if (weaverSlot != INVALID_WEAVER_SLOT) {
                     synchronizeWeaverFrpPassword(pwd, requestedQuality, userInfo.id, weaverSlot);
                 } else {
@@ -905,12 +911,17 @@
     private ArrayMap<Integer, ArrayMap<Long, TokenData>> tokenMap = new ArrayMap<>();
 
     /**
-     * Create a token based Synthetic password of the given type for the given user.
-     * @return the handle of the token
+     * Caches a pending escrow token in memory and pre-allocates an ID for a new SP protector.  This
+     * ID also serves as a handle for the pending token.
+     *
+     * This method doesn't persist any data, and it doesn't require access to the SP.
+     * {@link #createTokenBasedProtector} can be called later to actually create the protector.
+     *
+     * @return the token handle
      */
-    public long createTokenBasedSyntheticPassword(byte[] token, @TokenType int type, int userId,
+    public long addPendingToken(byte[] token, @TokenType int type, int userId,
             @Nullable EscrowTokenStateChangeCallback changeCallback) {
-        long handle = generateHandle();
+        long tokenHandle = generateProtectorId(); // tokenHandle is reused as protectorId later
         if (!tokenMap.containsKey(userId)) {
             tokenMap.put(userId, new ArrayMap<>());
         }
@@ -928,8 +939,8 @@
         tokenData.aggregatedSecret = transformUnderSecdiscardable(token, secdiscardable);
         tokenData.mCallback = changeCallback;
 
-        tokenMap.get(userId).put(handle, tokenData);
-        return handle;
+        tokenMap.get(userId).put(tokenHandle, tokenData);
+        return tokenHandle;
     }
 
     public Set<Long> getPendingTokensForUser(int userId) {
@@ -940,23 +951,22 @@
     }
 
     /** Remove the given pending token. */
-    public boolean removePendingToken(long handle, int userId) {
+    public boolean removePendingToken(long tokenHandle, int userId) {
         if (!tokenMap.containsKey(userId)) {
             return false;
         }
-        return tokenMap.get(userId).remove(handle) != null;
+        return tokenMap.get(userId).remove(tokenHandle) != null;
     }
 
-    public boolean activateTokenBasedSyntheticPassword(long handle, AuthenticationToken authToken,
-            int userId) {
+    public boolean createTokenBasedProtector(long tokenHandle, SyntheticPassword sp, int userId) {
         if (!tokenMap.containsKey(userId)) {
             return false;
         }
-        TokenData tokenData = tokenMap.get(userId).get(handle);
+        TokenData tokenData = tokenMap.get(userId).get(tokenHandle);
         if (tokenData == null) {
             return false;
         }
-        if (!loadEscrowData(authToken, userId)) {
+        if (!loadEscrowData(sp, userId)) {
             Slog.w(TAG, "User is not escrowable");
             return false;
         }
@@ -967,51 +977,52 @@
                 Slog.e(TAG, "Failed to enroll weaver secret when activating token");
                 return false;
             }
-            saveWeaverSlot(slot, handle, userId);
+            saveWeaverSlot(slot, tokenHandle, userId);
             mPasswordSlotManager.markSlotInUse(slot);
         }
-        saveSecdiscardable(handle, tokenData.secdiscardableOnDisk, userId);
-        createSyntheticPasswordBlob(handle, getTokenBasedBlobType(tokenData.mType), authToken,
+        saveSecdiscardable(tokenHandle, tokenData.secdiscardableOnDisk, userId);
+        createSyntheticPasswordBlob(tokenHandle, getTokenBasedProtectorType(tokenData.mType), sp,
                 tokenData.aggregatedSecret, 0L, userId);
-        tokenMap.get(userId).remove(handle);
+        tokenMap.get(userId).remove(tokenHandle);
         if (tokenData.mCallback != null) {
-            tokenData.mCallback.onEscrowTokenActivated(handle, userId);
+            tokenData.mCallback.onEscrowTokenActivated(tokenHandle, userId);
         }
         return true;
     }
 
-    private void createSyntheticPasswordBlob(long handle, byte type, AuthenticationToken authToken,
-            byte[] applicationId, long sid, int userId) {
-        final byte[] secret;
-        if (type == SYNTHETIC_PASSWORD_STRONG_TOKEN_BASED
-                || type == SYNTHETIC_PASSWORD_WEAK_TOKEN_BASED) {
-            secret = authToken.getEscrowSecret();
+    private void createSyntheticPasswordBlob(long protectorId, byte protectorType,
+            SyntheticPassword sp, byte[] protectorSecret, long sid, int userId) {
+        final byte[] spSecret;
+        if (protectorType == PROTECTOR_TYPE_STRONG_TOKEN_BASED
+                || protectorType == PROTECTOR_TYPE_WEAK_TOKEN_BASED) {
+            spSecret = sp.getEscrowSecret();
         } else {
-            secret = authToken.getSyntheticPassword();
+            spSecret = sp.getSyntheticPassword();
         }
-        byte[] content = createSPBlob(getKeyName(handle), secret, applicationId, sid);
+        byte[] content = createSPBlob(getKeyName(protectorId), spSecret, protectorSecret, sid);
         /*
          * We can upgrade from v1 to v2 because that's just a change in the way that
          * the SP is stored. However, we can't upgrade to v3 because that is a change
          * in the way that passwords are derived from the SP.
          */
-        byte version = authToken.mVersion == SYNTHETIC_PASSWORD_VERSION_V3
+        byte version = sp.mVersion == SYNTHETIC_PASSWORD_VERSION_V3
                 ? SYNTHETIC_PASSWORD_VERSION_V3 : SYNTHETIC_PASSWORD_VERSION_V2;
 
-        SyntheticPasswordBlob blob = SyntheticPasswordBlob.create(version, type, content);
-        saveState(SP_BLOB_NAME, blob.toByte(), handle, userId);
+        SyntheticPasswordBlob blob = SyntheticPasswordBlob.create(version, protectorType, content);
+        saveState(SP_BLOB_NAME, blob.toByte(), protectorId, userId);
     }
 
     /**
-     * Decrypt a synthetic password by supplying the user credential and corresponding password
-     * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
-     * verification to referesh the SID & Auth token maintained by the system.
+     * Tries to unlock a user's LSKF-based SP protector, given its ID and the claimed LSKF (which
+     * may be empty).  On success, returns the user's synthetic password, and also does a Gatekeeper
+     * verification to refresh the SID and HardwareAuthToken maintained by the system.
      */
-    public AuthenticationResult unwrapPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
-            long handle, @NonNull LockscreenCredential credential, int userId,
+    public AuthenticationResult unlockLskfBasedProtector(IGateKeeperService gatekeeper,
+            long protectorId, @NonNull LockscreenCredential credential, int userId,
             ICheckCredentialProgressCallback progressCallback) {
         AuthenticationResult result = new AuthenticationResult();
-        PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, handle, userId));
+        PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, protectorId,
+                    userId));
 
         if (!credential.checkAgainstStoredType(pwd.credentialType)) {
             Slog.e(TAG, String.format("Credential type mismatch: expected %d actual %d",
@@ -1022,13 +1033,13 @@
 
         byte[] pwdToken = computePasswordToken(credential, pwd);
 
-        final byte[] applicationId;
+        final byte[] protectorSecret;
         final long sid;
-        int weaverSlot = loadWeaverSlot(handle, userId);
+        int weaverSlot = loadWeaverSlot(protectorId, userId);
         if (weaverSlot != INVALID_WEAVER_SLOT) {
-            // Weaver based user password
+            // Protector uses Weaver to verify the LSKF
             if (!isWeaverAvailable()) {
-                Slog.e(TAG, "No weaver service to unwrap password based SP");
+                Slog.e(TAG, "Protector uses Weaver, but Weaver is unavailable");
                 result.gkResponse = VerifyCredentialResponse.ERROR;
                 return result;
             }
@@ -1037,9 +1048,10 @@
                 return result;
             }
             sid = GateKeeper.INVALID_SECURE_USER_ID;
-            applicationId = transformUnderWeaverSecret(pwdToken,
+            protectorSecret = transformUnderWeaverSecret(pwdToken,
                     result.gkResponse.getGatekeeperHAT());
         } else {
+            // Protector uses Gatekeeper to verify the LSKF
             byte[] gkPwdToken = passwordTokenToGkInput(pwdToken);
             GateKeeperResponse response;
             try {
@@ -1068,7 +1080,7 @@
                         // Use the reenrollment opportunity to update credential type
                         // (getting rid of CREDENTIAL_TYPE_PASSWORD_OR_PIN)
                         pwd.credentialType = credential.getType();
-                        saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
+                        saveState(PASSWORD_DATA_NAME, pwd.toBytes(), protectorId, userId);
                         synchronizeFrpPassword(pwd, 0, userId);
                     } else {
                         Slog.w(TAG, "Fail to re-enroll user password for user " + userId);
@@ -1083,8 +1095,8 @@
                 return result;
             }
             sid = sidFromPasswordHandle(pwd.passwordHandle);
-            applicationId = transformUnderSecdiscardable(pwdToken,
-                    loadSecdiscardable(handle, userId));
+            protectorSecret = transformUnderSecdiscardable(pwdToken,
+                    loadSecdiscardable(protectorId, userId));
         }
         // Supplied credential passes first stage weaver/gatekeeper check so it should be correct.
         // Notify the callback so the keyguard UI can proceed immediately.
@@ -1095,80 +1107,81 @@
                 Slog.w(TAG, "progressCallback throws exception", e);
             }
         }
-        result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED,
-                applicationId, sid, userId);
+        result.syntheticPassword = unwrapSyntheticPasswordBlob(protectorId,
+                PROTECTOR_TYPE_LSKF_BASED, protectorSecret, sid, userId);
 
         // Perform verifyChallenge to refresh auth tokens for GK if user password exists.
-        result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
+        result.gkResponse = verifyChallenge(gatekeeper, result.syntheticPassword, 0L, userId);
 
         // Upgrade case: store the metrics if the device did not have stored metrics before, should
-        // only happen once on old synthetic password blobs.
-        if (result.authToken != null && !hasPasswordMetrics(handle, userId)) {
-            savePasswordMetrics(credential, result.authToken, handle, userId);
+        // only happen once on old protectors.
+        if (result.syntheticPassword != null && !hasPasswordMetrics(protectorId, userId)) {
+            savePasswordMetrics(credential, result.syntheticPassword, protectorId, userId);
         }
         return result;
     }
 
     /**
-     * Decrypt a synthetic password by supplying an escrow token and corresponding token
-     * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
-     * verification to referesh the SID & Auth token maintained by the system.
+     * Tries to unlock a token-based SP protector (weak or strong), given its ID and the claimed
+     * token.  On success, returns the user's synthetic password, and also does a Gatekeeper
+     * verification to refresh the SID and HardwareAuthToken maintained by the system.
      */
-    public @NonNull AuthenticationResult unwrapTokenBasedSyntheticPassword(
-            IGateKeeperService gatekeeper, long handle, byte[] token, int userId) {
-        SyntheticPasswordBlob blob = SyntheticPasswordBlob
-                .fromBytes(loadState(SP_BLOB_NAME, handle, userId));
-        return unwrapTokenBasedSyntheticPasswordInternal(gatekeeper, handle,
-                blob.mType, token, userId);
+    public @NonNull AuthenticationResult unlockTokenBasedProtector(
+            IGateKeeperService gatekeeper, long protectorId, byte[] token, int userId) {
+        SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(loadState(SP_BLOB_NAME,
+                    protectorId, userId));
+        return unlockTokenBasedProtectorInternal(gatekeeper, protectorId, blob.mProtectorType,
+                token, userId);
     }
 
     /**
-     * Decrypt a synthetic password by supplying an strong escrow token and corresponding token
-     * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
-     * verification to referesh the SID & Auth token maintained by the system.
+     * Like {@link #unlockTokenBasedProtector}, but throws an exception if the protector is not for
+     * a strong token specifically.
      */
-    public @NonNull AuthenticationResult unwrapStrongTokenBasedSyntheticPassword(
-            IGateKeeperService gatekeeper, long handle, byte[] token, int userId) {
-        return unwrapTokenBasedSyntheticPasswordInternal(gatekeeper, handle,
-                SYNTHETIC_PASSWORD_STRONG_TOKEN_BASED, token, userId);
+    public @NonNull AuthenticationResult unlockStrongTokenBasedProtector(
+            IGateKeeperService gatekeeper, long protectorId, byte[] token, int userId) {
+        return unlockTokenBasedProtectorInternal(gatekeeper, protectorId,
+                PROTECTOR_TYPE_STRONG_TOKEN_BASED, token, userId);
     }
 
     /**
-     * Decrypt a synthetic password by supplying a weak escrow token and corresponding token
-     * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
-     * verification to referesh the SID & Auth token maintained by the system.
+     * Like {@link #unlockTokenBasedProtector}, but throws an exception if the protector is not for
+     * a weak token specifically.
      */
-    public @NonNull AuthenticationResult unwrapWeakTokenBasedSyntheticPassword(
-            IGateKeeperService gatekeeper, long handle, byte[] token, int userId) {
-        return unwrapTokenBasedSyntheticPasswordInternal(gatekeeper, handle,
-                SYNTHETIC_PASSWORD_WEAK_TOKEN_BASED, token, userId);
+    public @NonNull AuthenticationResult unlockWeakTokenBasedProtector(
+            IGateKeeperService gatekeeper, long protectorId, byte[] token, int userId) {
+        return unlockTokenBasedProtectorInternal(gatekeeper, protectorId,
+                PROTECTOR_TYPE_WEAK_TOKEN_BASED, token, userId);
     }
 
-    private  @NonNull AuthenticationResult unwrapTokenBasedSyntheticPasswordInternal(
-            IGateKeeperService gatekeeper, long handle, byte type, byte[] token, int userId) {
+    private @NonNull AuthenticationResult unlockTokenBasedProtectorInternal(
+            IGateKeeperService gatekeeper, long protectorId, byte expectedProtectorType,
+            byte[] token, int userId) {
         AuthenticationResult result = new AuthenticationResult();
-        byte[] secdiscardable = loadSecdiscardable(handle, userId);
-        int slotId = loadWeaverSlot(handle, userId);
+        byte[] secdiscardable = loadSecdiscardable(protectorId, userId);
+        int slotId = loadWeaverSlot(protectorId, userId);
         if (slotId != INVALID_WEAVER_SLOT) {
             if (!isWeaverAvailable()) {
-                Slog.e(TAG, "No weaver service to unwrap token based SP");
+                Slog.e(TAG, "Protector uses Weaver, but Weaver is unavailable");
                 result.gkResponse = VerifyCredentialResponse.ERROR;
                 return result;
             }
             VerifyCredentialResponse response = weaverVerify(slotId, null);
             if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK ||
                     response.getGatekeeperHAT() == null) {
-                Slog.e(TAG, "Failed to retrieve weaver secret when unwrapping token");
+                Slog.e(TAG,
+                        "Failed to retrieve Weaver secret when unlocking token-based protector");
                 result.gkResponse = VerifyCredentialResponse.ERROR;
                 return result;
             }
             secdiscardable = SyntheticPasswordCrypto.decrypt(response.getGatekeeperHAT(),
                     PERSONALIZATION_WEAVER_TOKEN, secdiscardable);
         }
-        byte[] applicationId = transformUnderSecdiscardable(token, secdiscardable);
-        result.authToken = unwrapSyntheticPasswordBlob(handle, type, applicationId, 0L, userId);
-        if (result.authToken != null) {
-            result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
+        byte[] protectorSecret = transformUnderSecdiscardable(token, secdiscardable);
+        result.syntheticPassword = unwrapSyntheticPasswordBlob(protectorId, expectedProtectorType,
+                protectorSecret, 0L, userId);
+        if (result.syntheticPassword != null) {
+            result.gkResponse = verifyChallenge(gatekeeper, result.syntheticPassword, 0L, userId);
             if (result.gkResponse == null) {
                 // The user currently has no password. return OK with null payload so null
                 // is propagated to unlockUser()
@@ -1180,9 +1193,9 @@
         return result;
     }
 
-    private AuthenticationToken unwrapSyntheticPasswordBlob(long handle, byte type,
-            byte[] applicationId, long sid, int userId) {
-        byte[] data = loadState(SP_BLOB_NAME, handle, userId);
+    private SyntheticPassword unwrapSyntheticPasswordBlob(long protectorId,
+            byte expectedProtectorType, byte[] protectorSecret, long sid, int userId) {
+        byte[] data = loadState(SP_BLOB_NAME, protectorId, userId);
         if (data == null) {
             return null;
         }
@@ -1190,36 +1203,38 @@
         if (blob.mVersion != SYNTHETIC_PASSWORD_VERSION_V3
                 && blob.mVersion != SYNTHETIC_PASSWORD_VERSION_V2
                 && blob.mVersion != SYNTHETIC_PASSWORD_VERSION_V1) {
-            throw new IllegalArgumentException("Unknown blob version");
+            throw new IllegalArgumentException("Unknown blob version: " + blob.mVersion);
         }
-        if (blob.mType != type) {
-            throw new IllegalArgumentException("Invalid blob type");
+        if (blob.mProtectorType != expectedProtectorType) {
+            throw new IllegalArgumentException("Invalid protector type: " + blob.mProtectorType);
         }
-        final byte[] secret;
+        final byte[] spSecret;
         if (blob.mVersion == SYNTHETIC_PASSWORD_VERSION_V1) {
-            secret = SyntheticPasswordCrypto.decryptBlobV1(getKeyName(handle), blob.mContent,
-                    applicationId);
+            spSecret = SyntheticPasswordCrypto.decryptBlobV1(getKeyName(protectorId), blob.mContent,
+                    protectorSecret);
         } else {
-            secret = decryptSPBlob(getKeyName(handle), blob.mContent, applicationId);
+            spSecret = decryptSPBlob(getKeyName(protectorId), blob.mContent, protectorSecret);
         }
-        if (secret == null) {
+        if (spSecret == null) {
             Slog.e(TAG, "Fail to decrypt SP for user " + userId);
             return null;
         }
-        AuthenticationToken result = new AuthenticationToken(blob.mVersion);
-        if (type == SYNTHETIC_PASSWORD_STRONG_TOKEN_BASED
-                || type == SYNTHETIC_PASSWORD_WEAK_TOKEN_BASED) {
+        SyntheticPassword result = new SyntheticPassword(blob.mVersion);
+        if (blob.mProtectorType == PROTECTOR_TYPE_STRONG_TOKEN_BASED
+                || blob.mProtectorType == PROTECTOR_TYPE_WEAK_TOKEN_BASED) {
             if (!loadEscrowData(result, userId)) {
                 Slog.e(TAG, "User is not escrowable: " + userId);
                 return null;
             }
-            result.recreateFromEscrow(secret);
+            result.recreateFromEscrow(spSecret);
         } else {
-            result.recreateDirectly(secret);
+            result.recreateDirectly(spSecret);
         }
         if (blob.mVersion == SYNTHETIC_PASSWORD_VERSION_V1) {
-            Slog.i(TAG, "Upgrade v1 SP blob for user " + userId + ", type = " + type);
-            createSyntheticPasswordBlob(handle, type, result, applicationId, sid, userId);
+            Slog.i(TAG, "Upgrading v1 SP blob for user " + userId + ", protectorType = "
+                    + blob.mProtectorType);
+            createSyntheticPasswordBlob(protectorId, blob.mProtectorType, result, protectorSecret,
+                    sid, userId);
         }
         return result;
     }
@@ -1228,13 +1243,12 @@
      * performs GK verifyChallenge and returns auth token, re-enrolling SP password handle
      * if required.
      *
-     * Normally performing verifyChallenge with an AuthenticationToken should always return
-     * RESPONSE_OK, since user authentication failures are detected earlier when trying to
-     * decrypt SP.
+     * Normally performing verifyChallenge with an SP should always return RESPONSE_OK, since user
+     * authentication failures are detected earlier when trying to decrypt the SP.
      */
     public @Nullable VerifyCredentialResponse verifyChallenge(IGateKeeperService gatekeeper,
-            @NonNull AuthenticationToken auth, long challenge, int userId) {
-        return verifyChallengeInternal(gatekeeper, auth.deriveGkPassword(), challenge, userId);
+            @NonNull SyntheticPassword sp, long challenge, int userId) {
+        return verifyChallengeInternal(gatekeeper, sp.deriveGkPassword(), challenge, userId);
     }
 
     protected @Nullable VerifyCredentialResponse verifyChallengeInternal(
@@ -1285,46 +1299,49 @@
         }
     }
 
-    public boolean existsHandle(long handle, int userId) {
-        return hasState(SP_BLOB_NAME, handle, userId);
+    public boolean protectorExists(long protectorId, int userId) {
+        return hasState(SP_BLOB_NAME, protectorId, userId);
     }
 
-    /** Destroy the escrow token with the given handle for the given user. */
-    public void destroyTokenBasedSyntheticPassword(long handle, int userId) {
-        SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(loadState(SP_BLOB_NAME, handle,
-                userId));
-        destroySyntheticPassword(handle, userId);
-        destroyState(SECDISCARDABLE_NAME, handle, userId);
-        if (blob.mType == SYNTHETIC_PASSWORD_WEAK_TOKEN_BASED) {
-            notifyWeakEscrowTokenRemovedListeners(handle, userId);
+    /** Destroy a token-based SP protector. */
+    public void destroyTokenBasedProtector(long protectorId, int userId) {
+        SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(loadState(SP_BLOB_NAME,
+                    protectorId, userId));
+        destroyProtectorCommon(protectorId, userId);
+        destroyState(SECDISCARDABLE_NAME, protectorId, userId);
+        if (blob.mProtectorType == PROTECTOR_TYPE_WEAK_TOKEN_BASED) {
+            notifyWeakEscrowTokenRemovedListeners(protectorId, userId);
         }
     }
 
-    /** Destroy all weak escrow tokens for the given user. */
-    public void destroyAllWeakTokenBasedSyntheticPasswords(int userId) {
-        List<Long> handles = mStorage.listSyntheticPasswordHandlesForUser(SECDISCARDABLE_NAME,
-                userId);
-        for (long handle: handles) {
+    /** Destroy all weak token-based SP protectors for the given user. */
+    public void destroyAllWeakTokenBasedProtectors(int userId) {
+        List<Long> protectorIds =
+            mStorage.listSyntheticPasswordProtectorsForUser(SECDISCARDABLE_NAME, userId);
+        for (long protectorId : protectorIds) {
             SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(loadState(SP_BLOB_NAME,
-                    handle, userId));
-            if (blob.mType == SYNTHETIC_PASSWORD_WEAK_TOKEN_BASED) {
-                destroyTokenBasedSyntheticPassword(handle, userId);
+                    protectorId, userId));
+            if (blob.mProtectorType == PROTECTOR_TYPE_WEAK_TOKEN_BASED) {
+                destroyTokenBasedProtector(protectorId, userId);
             }
         }
     }
 
-    public void destroyPasswordBasedSyntheticPassword(long handle, int userId) {
-        destroySyntheticPassword(handle, userId);
-        destroyState(SECDISCARDABLE_NAME, handle, userId);
-        destroyState(PASSWORD_DATA_NAME, handle, userId);
-        destroyState(PASSWORD_METRICS_NAME, handle, userId);
+    /**
+     * Destroy an LSKF-based SP protector.  This is used when the user's LSKF is changed.
+     */
+    public void destroyLskfBasedProtector(long protectorId, int userId) {
+        destroyProtectorCommon(protectorId, userId);
+        destroyState(SECDISCARDABLE_NAME, protectorId, userId);
+        destroyState(PASSWORD_DATA_NAME, protectorId, userId);
+        destroyState(PASSWORD_METRICS_NAME, protectorId, userId);
     }
 
-    private void destroySyntheticPassword(long handle, int userId) {
-        destroyState(SP_BLOB_NAME, handle, userId);
-        destroySPBlobKey(getKeyName(handle));
-        if (hasState(WEAVER_SLOT_NAME, handle, userId)) {
-            destroyWeaverSlot(handle, userId);
+    private void destroyProtectorCommon(long protectorId, int userId) {
+        destroyState(SP_BLOB_NAME, protectorId, userId);
+        destroySPBlobKey(getKeyName(protectorId));
+        if (hasState(WEAVER_SLOT_NAME, protectorId, userId)) {
+            destroyWeaverSlot(protectorId, userId);
         }
     }
 
@@ -1346,92 +1363,91 @@
         return result;
     }
 
-    private byte[] createSecdiscardable(long handle, int userId) {
+    private byte[] createSecdiscardable(long protectorId, int userId) {
         byte[] data = secureRandom(SECDISCARDABLE_LENGTH);
-        saveSecdiscardable(handle, data, userId);
+        saveSecdiscardable(protectorId, data, userId);
         return data;
     }
 
-    private void saveSecdiscardable(long handle, byte[] secdiscardable, int userId) {
-        saveState(SECDISCARDABLE_NAME, secdiscardable, handle, userId);
+    private void saveSecdiscardable(long protectorId, byte[] secdiscardable, int userId) {
+        saveState(SECDISCARDABLE_NAME, secdiscardable, protectorId, userId);
     }
 
-    private byte[] loadSecdiscardable(long handle, int userId) {
-        return loadState(SECDISCARDABLE_NAME, handle, userId);
+    private byte[] loadSecdiscardable(long protectorId, int userId) {
+        return loadState(SECDISCARDABLE_NAME, protectorId, userId);
     }
 
-    private byte getTokenBasedBlobType(@TokenType int type) {
+    private byte getTokenBasedProtectorType(@TokenType int type) {
         switch (type) {
             case TOKEN_TYPE_WEAK:
-                return SYNTHETIC_PASSWORD_WEAK_TOKEN_BASED;
+                return PROTECTOR_TYPE_WEAK_TOKEN_BASED;
             case TOKEN_TYPE_STRONG:
             default:
-                return SYNTHETIC_PASSWORD_STRONG_TOKEN_BASED;
+                return PROTECTOR_TYPE_STRONG_TOKEN_BASED;
         }
     }
 
     /**
-     * Retrieves the saved password metrics associated with a SP handle. Only meaningful to be
-     * called on the handle of a password-based synthetic password. A valid AuthenticationToken for
-     * the target user is required in order to be able to decrypt the encrypted password metrics on
-     * disk.
+     * Retrieves a user's saved password metrics from their LSKF-based SP protector.  The
+     * SyntheticPassword itself is needed to decrypt the file containing the password metrics.
      */
-    public @Nullable PasswordMetrics getPasswordMetrics(AuthenticationToken authToken, long handle,
+    public @Nullable PasswordMetrics getPasswordMetrics(SyntheticPassword sp, long protectorId,
             int userId) {
-        final byte[] encrypted = loadState(PASSWORD_METRICS_NAME, handle, userId);
+        final byte[] encrypted = loadState(PASSWORD_METRICS_NAME, protectorId, userId);
         if (encrypted == null) return null;
-        final byte[] decrypted = SyntheticPasswordCrypto.decrypt(authToken.deriveMetricsKey(),
+        final byte[] decrypted = SyntheticPasswordCrypto.decrypt(sp.deriveMetricsKey(),
                 /* personalization= */ new byte[0], encrypted);
         if (decrypted == null) return null;
         return VersionedPasswordMetrics.deserialize(decrypted).getMetrics();
     }
 
-    private void savePasswordMetrics(LockscreenCredential credential, AuthenticationToken authToken,
-            long handle, int userId) {
-        final byte[] encrypted = SyntheticPasswordCrypto.encrypt(authToken.deriveMetricsKey(),
+    private void savePasswordMetrics(LockscreenCredential credential, SyntheticPassword sp,
+            long protectorId, int userId) {
+        final byte[] encrypted = SyntheticPasswordCrypto.encrypt(sp.deriveMetricsKey(),
                 /* personalization= */ new byte[0],
                 new VersionedPasswordMetrics(credential).serialize());
-        saveState(PASSWORD_METRICS_NAME, encrypted, handle, userId);
+        saveState(PASSWORD_METRICS_NAME, encrypted, protectorId, userId);
     }
 
-    private boolean hasPasswordMetrics(long handle, int userId) {
-        return hasState(PASSWORD_METRICS_NAME, handle, userId);
+    private boolean hasPasswordMetrics(long protectorId, int userId) {
+        return hasState(PASSWORD_METRICS_NAME, protectorId, userId);
     }
 
-    private boolean hasState(String stateName, long handle, int userId) {
-        return !ArrayUtils.isEmpty(loadState(stateName, handle, userId));
+    private boolean hasState(String stateName, long protectorId, int userId) {
+        return !ArrayUtils.isEmpty(loadState(stateName, protectorId, userId));
     }
 
-    private byte[] loadState(String stateName, long handle, int userId) {
-        return mStorage.readSyntheticPasswordState(userId, handle, stateName);
+    private byte[] loadState(String stateName, long protectorId, int userId) {
+        return mStorage.readSyntheticPasswordState(userId, protectorId, stateName);
     }
 
-    private void saveState(String stateName, byte[] data, long handle, int userId) {
-        mStorage.writeSyntheticPasswordState(userId, handle, stateName, data);
+    private void saveState(String stateName, byte[] data, long protectorId, int userId) {
+        mStorage.writeSyntheticPasswordState(userId, protectorId, stateName, data);
     }
 
-    private void destroyState(String stateName, long handle, int userId) {
-        mStorage.deleteSyntheticPasswordState(userId, handle, stateName);
+    private void destroyState(String stateName, long protectorId, int userId) {
+        mStorage.deleteSyntheticPasswordState(userId, protectorId, stateName);
     }
 
-    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
-        return SyntheticPasswordCrypto.decryptBlob(blobKeyName, blob, applicationId);
+    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] protectorSecret) {
+        return SyntheticPasswordCrypto.decryptBlob(blobKeyName, blob, protectorSecret);
     }
 
-    protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) {
-        return SyntheticPasswordCrypto.createBlob(blobKeyName, data, applicationId, sid);
+    protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] protectorSecret,
+            long sid) {
+        return SyntheticPasswordCrypto.createBlob(blobKeyName, data, protectorSecret, sid);
     }
 
     protected void destroySPBlobKey(String keyAlias) {
         SyntheticPasswordCrypto.destroyBlobKey(keyAlias);
     }
 
-    public static long generateHandle() {
+    public static long generateProtectorId() {
         SecureRandom rng = new SecureRandom();
         long result;
         do {
             result = rng.nextLong();
-        } while (result == DEFAULT_HANDLE);
+        } while (result == NULL_PROTECTOR_ID);
         return result;
     }
 
@@ -1448,8 +1464,8 @@
         }
     }
 
-    private String getKeyName(long handle) {
-        return String.format("%s%x", LockPatternUtils.SYNTHETIC_PASSWORD_KEY_PREFIX, handle);
+    private String getKeyName(long protectorId) {
+        return String.format("%s%x", LockPatternUtils.SYNTHETIC_PASSWORD_KEY_PREFIX, protectorId);
     }
 
     private byte[] computePasswordToken(LockscreenCredential credential, PasswordData data) {
@@ -1506,11 +1522,11 @@
      */
     public boolean migrateKeyNamespace() {
         boolean success = true;
-        final Map<Integer, List<Long>> allHandles =
-                mStorage.listSyntheticPasswordHandlesForAllUsers(SP_BLOB_NAME);
-        for (List<Long> userHandles : allHandles.values()) {
-            for (long handle : userHandles) {
-                success &= SyntheticPasswordCrypto.migrateLockSettingsKey(getKeyName(handle));
+        final Map<Integer, List<Long>> allProtectors =
+            mStorage.listSyntheticPasswordProtectorsForAllUsers(SP_BLOB_NAME);
+        for (List<Long> userProtectors : allProtectors.values()) {
+            for (long protectorId : userProtectors) {
+                success &= SyntheticPasswordCrypto.migrateLockSettingsKey(getKeyName(protectorId));
             }
         }
         return success;
@@ -1528,13 +1544,13 @@
         return mListeners.unregister(listener);
     }
 
-    private void notifyWeakEscrowTokenRemovedListeners(long handle, int userId) {
+    private void notifyWeakEscrowTokenRemovedListeners(long protectorId, int userId) {
         int i = mListeners.beginBroadcast();
         try {
             while (i > 0) {
                 i--;
                 try {
-                    mListeners.getBroadcastItem(i).onWeakEscrowTokenRemoved(handle, userId);
+                    mListeners.getBroadcastItem(i).onWeakEscrowTokenRemoved(protectorId, userId);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "Exception while notifying WeakEscrowTokenRemovedListener.",
                             e);
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/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index f2a12b4..99a488c 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -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/NotificationHistoryDatabase.java b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
index e09f7b0..40c0a53 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
@@ -16,15 +16,8 @@
 
 package com.android.server.notification;
 
-import android.app.AlarmManager;
 import android.app.NotificationHistory;
 import android.app.NotificationHistory.HistoricalNotification;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.Uri;
 import android.os.Handler;
 import android.util.AtomicFile;
 import android.util.Slog;
@@ -61,18 +54,9 @@
     private static final String TAG = "NotiHistoryDatabase";
     private static final boolean DEBUG = NotificationManagerService.DBG;
     private static final int HISTORY_RETENTION_DAYS = 1;
-    private static final int HISTORY_RETENTION_MS = 24 * 60 * 60 * 1000;
     private static final long WRITE_BUFFER_INTERVAL_MS = 1000 * 60 * 20;
     private static final long INVALID_FILE_TIME_MS = -1;
 
-    private static final String ACTION_HISTORY_DELETION =
-            NotificationHistoryDatabase.class.getSimpleName() + ".CLEANUP";
-    private static final int REQUEST_CODE_DELETION = 1;
-    private static final String SCHEME_DELETION = "delete";
-    private static final String EXTRA_KEY = "key";
-
-    private final Context mContext;
-    private final AlarmManager mAlarmManager;
     private final Object mLock = new Object();
     private final Handler mFileWriteHandler;
     @VisibleForTesting
@@ -88,9 +72,7 @@
     @VisibleForTesting
     NotificationHistory mBuffer;
 
-    public NotificationHistoryDatabase(Context context, Handler fileWriteHandler, File dir) {
-        mContext = context;
-        mAlarmManager = context.getSystemService(AlarmManager.class);
+    public NotificationHistoryDatabase(Handler fileWriteHandler, File dir) {
         mCurrentVersion = DEFAULT_CURRENT_VERSION;
         mFileWriteHandler = fileWriteHandler;
         mVersionFile = new File(dir, "version");
@@ -98,11 +80,6 @@
         mHistoryFiles = new ArrayList<>();
         mBuffer = new NotificationHistory();
         mWriteBufferRunnable = new WriteBufferRunnable();
-
-        IntentFilter deletionFilter = new IntentFilter(ACTION_HISTORY_DELETION);
-        deletionFilter.addDataScheme(SCHEME_DELETION);
-        mContext.registerReceiver(mFileCleanupReceiver, deletionFilter,
-                Context.RECEIVER_EXPORTED_UNAUDITED);
     }
 
     public void init() {
@@ -118,7 +95,7 @@
 
             checkVersionAndBuildLocked();
             indexFilesLocked();
-            prune(HISTORY_RETENTION_DAYS, System.currentTimeMillis());
+            prune();
         }
     }
 
@@ -247,7 +224,14 @@
     }
 
     /**
-     * Remove any files that are too old and schedule jobs to clean up the rest
+     * Remove any files that are too old.
+     */
+    void prune() {
+        prune(HISTORY_RETENTION_DAYS, System.currentTimeMillis());
+    }
+
+    /**
+     * Remove any files that are too old.
      */
     void prune(final int retentionDays, final long currentTimeMillis) {
         synchronized (mLock) {
@@ -266,10 +250,6 @@
 
                 if (creationTime <= retentionBoundary.getTimeInMillis()) {
                     deleteFile(currentOldestFile);
-                } else {
-                    // all remaining files are newer than the cut off; schedule jobs to delete
-                    scheduleDeletion(
-                            currentOldestFile.getBaseFile(), creationTime, retentionDays);
                 }
             }
         }
@@ -307,26 +287,6 @@
         removeFilePathFromHistory(file.getBaseFile().getAbsolutePath());
     }
 
-    private void scheduleDeletion(File file, long creationTime, int retentionDays) {
-        final long deletionTime = creationTime + (retentionDays * HISTORY_RETENTION_MS);
-        scheduleDeletion(file, deletionTime);
-    }
-
-    private void scheduleDeletion(File file, long deletionTime) {
-        if (DEBUG) {
-            Slog.d(TAG, "Scheduling deletion for " + file.getName() + " at " + deletionTime);
-        }
-        final PendingIntent pi = PendingIntent.getBroadcast(mContext,
-                REQUEST_CODE_DELETION,
-                new Intent(ACTION_HISTORY_DELETION)
-                        .setData(new Uri.Builder().scheme(SCHEME_DELETION)
-                                .appendPath(file.getAbsolutePath()).build())
-                        .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
-                        .putExtra(EXTRA_KEY, file.getAbsolutePath()),
-                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
-        mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, deletionTime, pi);
-    }
-
     private void writeLocked(AtomicFile file, NotificationHistory notifications)
             throws IOException {
         FileOutputStream fos = file.startWrite();
@@ -356,12 +316,6 @@
         }
     }
 
-    public void unregisterFileCleanupReceiver() {
-        if(mContext != null) {
-            mContext.unregisterReceiver(mFileCleanupReceiver);
-        }
-    }
-
     private static long safeParseLong(String fileName) {
         // AtomicFile will create copies of the numeric files with ".new" and ".bak"
         // over the course of its processing. If these files still exist on boot we need to clean
@@ -373,40 +327,15 @@
         }
     }
 
-    private final BroadcastReceiver mFileCleanupReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (action == null) {
-                return;
-            }
-            if (ACTION_HISTORY_DELETION.equals(action)) {
-                try {
-                    synchronized (mLock) {
-                        final String filePath = intent.getStringExtra(EXTRA_KEY);
-                        AtomicFile fileToDelete = new AtomicFile(new File(filePath));
-                        if (DEBUG) {
-                            Slog.d(TAG, "Removed " + fileToDelete.getBaseFile().getName());
-                        }
-                        fileToDelete.delete();
-                        removeFilePathFromHistory(filePath);
-                    }
-                } catch (Exception e) {
-                    Slog.e(TAG, "Failed to delete notification history file", e);
-                }
-            }
-        }
-    };
-
     final class WriteBufferRunnable implements Runnable {
 
         @Override
         public void run() {
             long time = System.currentTimeMillis();
-            run(time, new AtomicFile(new File(mHistoryDir, String.valueOf(time))));
+            run(new AtomicFile(new File(mHistoryDir, String.valueOf(time))));
         }
 
-        void run(long time, AtomicFile file) {
+        void run(AtomicFile file) {
             synchronized (mLock) {
                 if (DEBUG) Slog.d(TAG, "WriteBufferRunnable "
                         + file.getBaseFile().getAbsolutePath());
@@ -414,8 +343,6 @@
                     writeLocked(file, mBuffer);
                     mHistoryFiles.add(0, file);
                     mBuffer = new NotificationHistory();
-
-                    scheduleDeletion(file.getBaseFile(), time, HISTORY_RETENTION_DAYS);
                 } catch (IOException e) {
                     Slog.e(TAG, "Failed to write buffer to disk. not flushing buffer", e);
                 }
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryDatabaseFactory.java b/services/core/java/com/android/server/notification/NotificationHistoryDatabaseFactory.java
index d9e0d79..0d975cc 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryDatabaseFactory.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryDatabaseFactory.java
@@ -35,6 +35,6 @@
         if(sTestingNotificationHistoryDb != null) {
             return sTestingNotificationHistoryDb;
         }
-        return new NotificationHistoryDatabase(context, handler, rootDir);
+        return new NotificationHistoryDatabase(handler, rootDir);
     }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryJobService.java b/services/core/java/com/android/server/notification/NotificationHistoryJobService.java
new file mode 100644
index 0000000..3776ad7
--- /dev/null
+++ b/services/core/java/com/android/server/notification/NotificationHistoryJobService.java
@@ -0,0 +1,81 @@
+/*
+ * 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.notification;
+
+import static android.app.job.JobScheduler.RESULT_SUCCESS;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.CancellationSignal;
+import android.util.Slog;
+
+import com.android.server.LocalServices;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This service runs every twenty minutes to ensure the retention policy for notification history
+ * data.
+ */
+public class NotificationHistoryJobService extends JobService {
+    private final static String TAG = "NotificationHistoryJob";
+    private static final long JOB_RUN_INTERVAL = TimeUnit.MINUTES.toMillis(20);
+
+    static final int BASE_JOB_ID = 237039804;
+
+    static void scheduleJob(Context context) {
+        JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
+        if (jobScheduler.getPendingJob(BASE_JOB_ID) == null) {
+            ComponentName component =
+                    new ComponentName(context, NotificationHistoryJobService.class);
+            JobInfo newJob = new JobInfo.Builder(BASE_JOB_ID, component)
+                    .setRequiresDeviceIdle(false)
+                    .setPeriodic(JOB_RUN_INTERVAL)
+                    .build();
+            if (jobScheduler.schedule(newJob) != RESULT_SUCCESS) {
+                Slog.w(TAG, "Failed to schedule history cleanup job");
+            }
+        }
+    }
+
+    private CancellationSignal mSignal;
+
+    @Override
+    public boolean onStartJob(JobParameters params) {
+        mSignal = new CancellationSignal();
+        new Thread(() -> {
+            NotificationManagerInternal nmInternal =
+                    LocalServices.getService(NotificationManagerInternal.class);
+            nmInternal.cleanupHistoryFiles();
+            jobFinished(params, mSignal.isCanceled());
+        }).start();
+        return true;
+    }
+
+    @Override
+    public boolean onStopJob(JobParameters params) {
+        if (mSignal != null) {
+            mSignal.cancel();
+        }
+        return false;
+    }
+}
+
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryManager.java b/services/core/java/com/android/server/notification/NotificationHistoryManager.java
index 0aacd13..6a46048 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryManager.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryManager.java
@@ -84,6 +84,11 @@
     }
 
     void onBootPhaseAppsCanStart() {
+        try {
+            NotificationHistoryJobService.scheduleJob(mContext);
+        } catch (Throwable e) {
+            Slog.e(TAG, "Failed to schedule cleanup job", e);
+        }
         mSettingsObserver.observe();
     }
 
@@ -151,6 +156,24 @@
         }
     }
 
+    public void cleanupHistoryFiles() {
+        synchronized (mLock) {
+            int n = mUserUnlockedStates.size();
+            for (int i = 0;  i < n; i++) {
+                // cleanup old files for currently unlocked users. User are additionally cleaned
+                // on unlock in NotificationHistoryDatabase.init().
+                if (mUserUnlockedStates.valueAt(i)) {
+                    final NotificationHistoryDatabase userHistory =
+                            mUserState.get(mUserUnlockedStates.keyAt(i));
+                    if (userHistory == null) {
+                        continue;
+                    }
+                    userHistory.prune();
+                }
+            }
+        }
+    }
+
     public void deleteNotificationHistoryItem(String pkg, int uid, long postedTime) {
         synchronized (mLock) {
             int userId = UserHandle.getUserId(uid);
@@ -288,7 +311,6 @@
 
     private void disableHistory(NotificationHistoryDatabase userHistory, @UserIdInt int userId) {
         userHistory.disableHistory();
-        userHistory.unregisterFileCleanupReceiver();
 
         mUserPendingHistoryDisables.put(userId, false);
         mHistoryEnabled.put(userId, false);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerInternal.java b/services/core/java/com/android/server/notification/NotificationManagerInternal.java
index 8a62736..bc38856 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerInternal.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerInternal.java
@@ -45,4 +45,6 @@
 
     /** Send a notification to the user prompting them to review their notification permissions. */
     void sendReviewPermissionsNotification();
+
+    void cleanupHistoryFiles();
 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index e35e4c9..f8604c0 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);
             }
@@ -2733,7 +2734,7 @@
     }
 
     @Override
-    public void onUserUnlocking(@NonNull TargetUser user) {
+    public void onUserUnlocked(@NonNull TargetUser user) {
         mHandler.post(() -> {
             Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "notifHistoryUnlockUser");
             try {
@@ -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();
@@ -6345,6 +6344,12 @@
                     Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
                     NotificationManagerService.REVIEW_NOTIF_STATE_RESHOWN);
         }
+
+        @Override
+        public void cleanupHistoryFiles() {
+            checkCallerIsSystem();
+            mHistoryManager.cleanupHistoryFiles();
+        }
     };
 
     int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted) {
@@ -9919,10 +9924,16 @@
      * given NAS is bound in.
      */
     private boolean isInteractionVisibleToListener(ManagedServiceInfo info, int userId) {
-        boolean isAssistantService = mAssistants.isServiceTokenValidLocked(info.service);
+        boolean isAssistantService = isServiceTokenValid(info.service);
         return !isAssistantService || info.isSameUser(userId);
     }
 
+    private boolean isServiceTokenValid(IInterface service) {
+        synchronized (mNotificationLock) {
+            return mAssistants.isServiceTokenValidLocked(service);
+        }
+    }
+
     private boolean isPackageSuspendedForUser(String pkg, int uid) {
         final long identity = Binder.clearCallingIdentity();
         int userId = UserHandle.getUserId(uid);
@@ -11184,7 +11195,7 @@
                 BackgroundThread.getHandler().post(() -> {
                     if (info.isSystem
                             || hasCompanionDevice(info)
-                            || mAssistants.isServiceTokenValidLocked(info.service)) {
+                            || isServiceTokenValid(info.service)) {
                         notifyNotificationChannelChanged(
                                 info, pkg, user, channel, modificationType);
                     }
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 15d7c1e..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,7 +54,7 @@
 /**
  * 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;
@@ -68,8 +63,6 @@
 
     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";
@@ -91,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();
@@ -125,21 +113,9 @@
         mUserProfiles = userProfiles;
     }
 
-    private String getPkgKey(@UserIdInt int userId, String pkg) {
-        return userId + "|" + pkg;
-    }
-
-    void cleanupPersistedContext(String key){
-        synchronized (mLock) {
-            int userId = mUsers.get(key);
-            String pkg = mPackages.get(key);
-            removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotificationsWithContext);
-        }
-    }
-
     protected boolean canSnooze(int numberToSnooze) {
         synchronized (mLock) {
-            if ((mPackages.size() + numberToSnooze) > CONCURRENT_SNOOZE_LIMIT) {
+            if ((mSnoozedNotifications.size() + numberToSnooze) > CONCURRENT_SNOOZE_LIMIT) {
                 return false;
             }
         }
@@ -150,11 +126,7 @@
     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;
@@ -164,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
@@ -194,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);
                 }
             }
         }
@@ -211,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;
         }
     }
@@ -244,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);
         }
     }
 
@@ -260,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;
                 }
             }
         }
@@ -336,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;
                 }
             }
         }
@@ -348,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;
         }
@@ -366,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);
             }
         }
     }
@@ -387,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();
@@ -432,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();
                 }
@@ -451,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));
                     };
@@ -474,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);
@@ -528,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));
             }
         }
     }
@@ -589,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);
         }
     }
 
@@ -639,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);
                             }
                         }
                     }
@@ -656,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/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/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/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 379b132..8bb9b84 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -463,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);
@@ -3417,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);
         });
 
 
@@ -3771,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();
             }
 
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/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..e55424a 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);
     }
 
     /**
@@ -4792,6 +4789,9 @@
                 pw.println();
         pw.print(prefix); pw.print("  pkgFlags="); printFlags(pw, ps.getFlags(), FLAG_DUMP_SPEC);
                 pw.println();
+        pw.print(prefix); pw.print("  privatePkgFlags="); printFlags(pw, ps.getPrivateFlags(),
+                PRIVATE_FLAG_DUMP_SPEC);
+        pw.println();
 
         if (pkg != null && pkg.getOverlayTarget() != null) {
             pw.print(prefix); pw.print("  overlayTarget="); pw.println(pkg.getOverlayTarget());
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/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/power/stats/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/power/stats/BatteryExternalStatsWorker.java
index 3758e88..fe4aa53 100644
--- a/services/core/java/com/android/server/power/stats/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/power/stats/BatteryExternalStatsWorker.java
@@ -257,11 +257,6 @@
     }
 
     @Override
-    public synchronized Future<?> scheduleCpuSyncDueToSettingChange() {
-        return scheduleSyncLocked("setting-change", UPDATE_CPU);
-    }
-
-    @Override
     public Future<?> scheduleSyncDueToScreenStateChange(int flags, boolean onBattery,
             boolean onBatteryScreenOff, int screenState, int[] perDisplayScreenStates) {
         synchronized (BatteryExternalStatsWorker.this) {
diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
index 2647560..0c9ada8 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -150,7 +150,6 @@
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Collection;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -178,9 +177,6 @@
 
     // TODO: remove "tcp" from network methods, since we measure total stats.
 
-    // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
-    private static final int MAGIC = 0xBA757475; // 'BATSTATS'
-
     // Current on-disk Parcel version. Must be updated when the format of the parcelable changes
     public static final int VERSION = 209;
 
@@ -647,7 +643,7 @@
 
         Future<?> scheduleSync(String reason, int flags);
         Future<?> scheduleCpuSyncDueToRemovedUid(int uid);
-        Future<?> scheduleCpuSyncDueToSettingChange();
+
         /**
          * Schedule a sync because of a screen state change.
          */
@@ -716,10 +712,6 @@
     // is unplugged from power *and* the screen is off or doze.
     protected final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase(true);
 
-    // Set to true when we want to distribute CPU across wakelocks for the next
-    // CPU update, even if we aren't currently running wake locks.
-    boolean mDistributeWakelockCpu;
-
     private boolean mSystemReady;
     boolean mShuttingDown;
 
@@ -753,16 +745,10 @@
 
     final HistoryItem mHistoryCur = new HistoryItem();
 
-    HistoryItem mHistory;
-    HistoryItem mHistoryEnd;
-    HistoryItem mHistoryLastEnd;
-    HistoryItem mHistoryCache;
-
     // Used by computeHistoryStepDetails
     HistoryStepDetails mLastHistoryStepDetails = null;
     byte mLastHistoryStepLevel = 0;
     final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails();
-    final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails();
     final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails();
 
     /**
@@ -1398,12 +1384,10 @@
      * External reporting of whether the device is actually charging.
      */
     boolean mCharging = true;
-    int mLastChargingStateLevel;
 
     /*
-     * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
+     * These keep track of battery levels (1-100) at the last unplug event.
      */
-    int mDischargeStartLevel;
     int mDischargeUnplugLevel;
     int mDischargePlugLevel;
     int mDischargeCurrentLevel;
@@ -1943,36 +1927,6 @@
         public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) {
         }
 
-        /**
-         * Writes a possibly null Counter to a Parcel.
-         *
-         * @param out the Parcel to be written to.
-         * @param counter a Counter, or null.
-         */
-        public static void writeCounterToParcel(Parcel out, @Nullable Counter counter) {
-            if (counter == null) {
-                out.writeInt(0); // indicates null
-                return;
-            }
-            out.writeInt(1); // indicates non-null
-
-            counter.writeToParcel(out);
-        }
-
-        /**
-         * Reads a Counter that was written using {@link #writeCounterToParcel(Parcel, Counter)}.
-         * @param timeBase the timebase to assign to the Counter
-         * @param in the parcel to read from
-         * @return the Counter or null.
-         */
-        @Nullable
-        public static Counter readCounterFromParcel(TimeBase timeBase, Parcel in) {
-            if (in.readInt() == 0) {
-                return null;
-            }
-            return new Counter(timeBase, in);
-        }
-
         @Override
         public int getCountLocked(int which) {
             return mCount.get();
@@ -2701,13 +2655,6 @@
          * @param totalTimeUs total time of sample in microseconds.
          * @param count total number of times the event being sampled occurred.
          */
-        public void updated(long totalTimeUs, int count) {
-            update(totalTimeUs, count, mClock.elapsedRealtime() * 1000);
-        }
-
-        /**
-         * @see #update(long, int)
-         */
         public void update(long totalTimeUs, int count, long elapsedRealtimeUs) {
             if (mTimeBaseRunning && !mTrackingReportedValues) {
                 // Updating the reported value for the first time.
@@ -2893,11 +2840,7 @@
             }
         }
 
-        public void addDuration(BatteryStatsImpl stats, long durationMs) {
-            addDuration(stats, durationMs, mClock.elapsedRealtime());
-        }
-
-        public void addDuration(BatteryStatsImpl stats, long durationMs, long elapsedRealtimeMs) {
+        public void addDuration(long durationMs, long elapsedRealtimeMs) {
             final long nowUs = elapsedRealtimeMs * 1000;
             recomputeLastDuration(nowUs, true);
             mLastAddedTimeUs = nowUs;
@@ -2908,11 +2851,7 @@
             }
         }
 
-        public void abortLastDuration(BatteryStatsImpl stats) {
-            abortLastDuration(stats, mClock.elapsedRealtime());
-        }
-
-        public void abortLastDuration(BatteryStatsImpl stats, long elapsedRealtimeMs) {
+        public void abortLastDuration(long elapsedRealtimeMs) {
             final long nowUs = elapsedRealtimeMs * 1000;
             recomputeLastDuration(nowUs, true);
         }
@@ -3685,21 +3624,6 @@
             mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase);
         }
 
-        public ControllerActivityCounterImpl(Clock clock, TimeBase timeBase, int numTxStates,
-                Parcel in) {
-            mClock = clock;
-            mTimeBase = timeBase;
-            mNumTxStates = numTxStates;
-            mIdleTimeMillis = readTimeMultiStateCounter(in, timeBase);
-            mScanTimeMillis = new LongSamplingCounter(timeBase, in);
-            mSleepTimeMillis = new LongSamplingCounter(timeBase, in);
-            mRxTimeMillis = readTimeMultiStateCounter(in, timeBase);
-            mTxTimeMillis = readTimeMultiStateCounters(in, timeBase, numTxStates);
-
-            mPowerDrainMaMs = new LongSamplingCounter(timeBase, in);
-            mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase, in);
-        }
-
         public void readSummaryFromParcel(Parcel in) {
             mIdleTimeMillis = readTimeMultiStateCounter(in, mTimeBase);
             mScanTimeMillis.readSummaryFromParcelLocked(in);
@@ -4273,12 +4197,6 @@
                 | ((((int)h.batteryVoltage)<<1)&0x00007ffe);
     }
 
-    private void readBatteryLevelInt(int batteryLevelInt, HistoryItem out) {
-        out.batteryLevel = (byte)((batteryLevelInt & 0xfe000000) >>> 25);
-        out.batteryTemperature = (short)((batteryLevelInt & 0x01ff8000) >>> 15);
-        out.batteryVoltage = (char)((batteryLevelInt & 0x00007ffe) >>> 1);
-    }
-
     private int buildStateInt(HistoryItem h) {
         int plugType = 0;
         if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) {
@@ -4575,32 +4493,6 @@
     }
 
     @GuardedBy("this")
-    void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) {
-        HistoryItem rec = mHistoryCache;
-        if (rec != null) {
-            mHistoryCache = rec.next;
-        } else {
-            rec = new HistoryItem();
-        }
-        rec.setTo(mHistoryBaseTimeMs + elapsedRealtimeMs, cmd, cur);
-
-        addHistoryRecordLocked(rec);
-    }
-
-    @GuardedBy("this")
-    void addHistoryRecordLocked(HistoryItem rec) {
-        mNumHistoryItems++;
-        rec.next = null;
-        mHistoryLastEnd = mHistoryEnd;
-        if (mHistoryEnd != null) {
-            mHistoryEnd.next = rec;
-            mHistoryEnd = rec;
-        } else {
-            mHistory = mHistoryEnd = rec;
-        }
-    }
-
-    @GuardedBy("this")
     void clearHistoryLocked() {
         if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
         mHistoryBaseTimeMs = 0;
@@ -4765,11 +4657,6 @@
     }
 
     @GuardedBy("this")
-    public void noteEventLocked(int code, String name, int uid) {
-        noteEventLocked(code, name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteEventLocked(int code, String name, int uid,
             long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
@@ -4780,25 +4667,12 @@
     }
 
     @GuardedBy("this")
-    public void noteCurrentTimeChangedLocked() {
-        final long currentTime = mClock.currentTimeMillis();
-        final long elapsedRealtime = mClock.elapsedRealtime();
-        final long uptime = mClock.uptimeMillis();
-        noteCurrentTimeChangedLocked(currentTime, elapsedRealtime, uptime);
-    }
-
-    @GuardedBy("this")
     public void noteCurrentTimeChangedLocked(long currentTimeMs,
             long elapsedRealtimeMs, long uptimeMs) {
         recordCurrentTimeChangeLocked(currentTimeMs, elapsedRealtimeMs, uptimeMs);
     }
 
     @GuardedBy("this")
-    public void noteProcessStartLocked(String name, int uid) {
-        noteProcessStartLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteProcessStartLocked(String name, int uid,
             long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
@@ -4816,11 +4690,6 @@
     }
 
     @GuardedBy("this")
-    public void noteProcessCrashLocked(String name, int uid) {
-        noteProcessCrashLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteProcessCrashLocked(String name, int uid,
             long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
@@ -4831,11 +4700,6 @@
     }
 
     @GuardedBy("this")
-    public void noteProcessAnrLocked(String name, int uid) {
-        noteProcessAnrLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
         if (isOnBattery()) {
@@ -4871,11 +4735,6 @@
     }
 
     @GuardedBy("this")
-    public void noteProcessFinishLocked(String name, int uid) {
-        noteProcessFinishLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteProcessFinishLocked(String name, int uid,
             long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
@@ -4957,12 +4816,6 @@
     }
 
     @GuardedBy("this")
-    public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast) {
-        noteJobsDeferredLocked(uid, numDeferred, sinceLast,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast,
             long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
@@ -5137,9 +4990,6 @@
         }
     }
 
-    private String mInitialAcquireWakeName;
-    private int mInitialAcquireWakeUid = -1;
-
     @GuardedBy("this")
     public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName,
             int type, boolean unimportantForLogging) {
@@ -5170,8 +5020,8 @@
                 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
                         + Integer.toHexString(mHistoryCur.states));
                 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
-                mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
-                mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = mappedUid;
+                mHistoryCur.wakelockTag.string = historyName;
+                mHistoryCur.wakelockTag.uid = mappedUid;
                 mWakeLockImportant = !unimportantForLogging;
                 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
             } else if (!mWakeLockImportant && !unimportantForLogging
@@ -5180,8 +5030,8 @@
                     // We'll try to update the last tag.
                     mHistoryLastWritten.wakelockTag = null;
                     mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
-                    mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
-                    mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = mappedUid;
+                    mHistoryCur.wakelockTag.string = historyName;
+                    mHistoryCur.wakelockTag.uid = mappedUid;
                     addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
                 }
                 mWakeLockImportant = true;
@@ -5245,8 +5095,6 @@
                 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
                 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
                         + Integer.toHexString(mHistoryCur.states));
-                mInitialAcquireWakeName = null;
-                mInitialAcquireWakeUid = -1;
                 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
             }
         }
@@ -5310,13 +5158,6 @@
 
     @GuardedBy("this")
     public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
-            String historyName, int type, boolean unimportantForLogging) {
-        noteStartWakeFromSourceLocked(ws, pid, name, historyName, type, unimportantForLogging,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
-    public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
             String historyName, int type, boolean unimportantForLogging,
             long elapsedRealtimeMs, long uptimeMs) {
         final int N = ws.size();
@@ -5338,15 +5179,6 @@
     @GuardedBy("this")
     public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name,
             String historyName, int type, WorkSource newWs, int newPid, String newName,
-            String newHistoryName, int newType, boolean newUnimportantForLogging) {
-        noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type, newWs, newPid,
-                newName, newHistoryName, newType, newUnimportantForLogging,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
-    public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name,
-            String historyName, int type, WorkSource newWs, int newPid, String newName,
             String newHistoryName, int newType, boolean newUnimportantForLogging,
             long elapsedRealtimeMs, long uptimeMs) {
         List<WorkChain>[] wcs = WorkSource.diffChains(ws, newWs);
@@ -5393,13 +5225,6 @@
 
     @GuardedBy("this")
     public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name,
-            String historyName, int type) {
-        noteStopWakeFromSourceLocked(ws, pid, name, historyName, type,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
-    public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name,
             String historyName, int type, long elapsedRealtimeMs, long uptimeMs) {
         final int N = ws.size();
         for (int i=0; i<N; i++) {
@@ -5431,13 +5256,6 @@
 
     @GuardedBy("this")
     public void noteLongPartialWakelockStartFromSource(String name, String historyName,
-            WorkSource workSource) {
-        noteLongPartialWakelockStartFromSource(name, historyName, workSource,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
-    public void noteLongPartialWakelockStartFromSource(String name, String historyName,
             WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) {
         final int N = workSource.size();
         for (int i = 0; i < N; ++i) {
@@ -5491,13 +5309,6 @@
 
     @GuardedBy("this")
     public void noteLongPartialWakelockFinishFromSource(String name, String historyName,
-            WorkSource workSource) {
-        noteLongPartialWakelockFinishFromSource(name, historyName, workSource,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
-    public void noteLongPartialWakelockFinishFromSource(String name, String historyName,
             WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) {
         final int N = workSource.size();
         for (int i = 0; i < N; ++i) {
@@ -5549,11 +5360,6 @@
     }
 
     @GuardedBy("this")
-    public void noteWakeupReasonLocked(String reason) {
-        noteWakeupReasonLocked(reason, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs) {
         if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": "
                 + Integer.toHexString(mHistoryCur.states));
@@ -5600,18 +5406,6 @@
         }
     }
 
-    public long getProcessWakeTime(int uid, int pid, long realtimeMs) {
-        uid = mapUid(uid);
-        Uid u = mUidStats.get(uid);
-        if (u != null) {
-            Uid.Pid p = u.mPids.get(pid);
-            if (p != null) {
-                return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtimeMs - p.mWakeStartMs) : 0);
-            }
-        }
-        return 0;
-    }
-
     public void reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs) {
         uid = mapUid(uid);
         Uid u = mUidStats.get(uid);
@@ -5753,11 +5547,6 @@
     }
 
     @GuardedBy("this")
-    public void noteGpsSignalQualityLocked(int signalLevel) {
-        noteGpsSignalQualityLocked(signalLevel, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs) {
         if (mGpsNesting == 0) {
             return;
@@ -6025,11 +5814,6 @@
         }
     }
 
-    @GuardedBy("this")
-    public void noteScreenBrightnessLocked(int brightness) {
-        noteScreenBrightnessLocked(0, brightness);
-    }
-
     /**
      * Note screen brightness change for a display.
      */
@@ -6127,11 +5911,6 @@
     }
 
     @GuardedBy("this")
-    public void noteUserActivityLocked(int uid, int event) {
-        noteUserActivityLocked(uid, event, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteUserActivityLocked(int uid, int event, long elapsedRealtimeMs, long uptimeMs) {
         if (mOnBatteryInternal) {
             uid = mapUid(uid);
@@ -6140,11 +5919,6 @@
     }
 
     @GuardedBy("this")
-    public void noteWakeUpLocked(String reason, int reasonUid) {
-        noteWakeUpLocked(reason, reasonUid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteWakeUpLocked(String reason, int reasonUid,
             long elapsedRealtimeMs, long uptimeMs) {
         addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SCREEN_WAKE_UP,
@@ -6152,11 +5926,6 @@
     }
 
     @GuardedBy("this")
-    public void noteInteractiveLocked(boolean interactive) {
-        noteInteractiveLocked(interactive, mClock.elapsedRealtime());
-    }
-
-    @GuardedBy("this")
     public void noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs) {
         if (mInteractive != interactive) {
             mInteractive = interactive;
@@ -6170,12 +5939,6 @@
     }
 
     @GuardedBy("this")
-    public void noteConnectivityChangedLocked(int type, String extra) {
-        noteConnectivityChangedLocked(type, extra,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteConnectivityChangedLocked(int type, String extra,
             long elapsedRealtimeMs, long uptimeMs) {
         addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_CONNECTIVITY_CHANGED,
@@ -6253,11 +6016,6 @@
                 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
     }
 
-    @GuardedBy("this")
-    public void notePowerSaveModeLocked(boolean enabled) {
-        notePowerSaveModeLocked(enabled, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
     /**
      * Toggles the power save mode state.
      */
@@ -6303,12 +6061,6 @@
     }
 
     @GuardedBy("this")
-    public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid) {
-        noteDeviceIdleModeLocked(mode, activeReason, activeUid,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid,
             long elapsedRealtimeMs, long uptimeMs) {
         boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP;
@@ -6383,12 +6135,6 @@
     }
 
     @GuardedBy("this")
-    public void notePackageInstalledLocked(String pkgName, long versionCode) {
-        notePackageInstalledLocked(pkgName, versionCode,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void notePackageInstalledLocked(String pkgName, long versionCode,
             long elapsedRealtimeMs, long uptimeMs) {
         // XXX need to figure out what to do with long version codes.
@@ -6402,11 +6148,6 @@
     }
 
     @GuardedBy("this")
-    public void notePackageUninstalledLocked(String pkgName) {
-        notePackageUninstalledLocked(pkgName, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void notePackageUninstalledLocked(String pkgName,
             long elapsedRealtimeMs, long uptimeMs) {
         addHistoryEventLocked(elapsedRealtimeMs, uptimeMs,
@@ -6425,11 +6166,6 @@
     }
 
     @GuardedBy("this")
-    void stopAllGpsSignalQualityTimersLocked(int except) {
-        stopAllGpsSignalQualityTimersLocked(except, mClock.elapsedRealtime());
-    }
-
-    @GuardedBy("this")
     void stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs) {
         for (int i = 0; i < mGpsSignalQualityTimer.length; i++) {
             if (i == except) {
@@ -6442,11 +6178,6 @@
     }
 
     @GuardedBy("this")
-    public void notePhoneOnLocked() {
-        notePhoneOnLocked(mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (!mPhoneOn) {
             mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
@@ -6459,11 +6190,6 @@
     }
 
     @GuardedBy("this")
-    public void notePhoneOffLocked() {
-        notePhoneOffLocked(mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (mPhoneOn) {
             mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
@@ -6527,19 +6253,6 @@
         }
     }
 
-    private int fixPhoneServiceState(int state, int signalBin) {
-        if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
-            // In this case we will always be STATE_OUT_OF_SERVICE, so need
-            // to infer that we are scanning from other data.
-            if (state == ServiceState.STATE_OUT_OF_SERVICE
-                    && signalBin > CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
-                state = ServiceState.STATE_IN_SERVICE;
-            }
-        }
-
-        return state;
-    }
-
     @GuardedBy("this")
     private void updateAllPhoneStateLocked(int state, int simState, int strengthBin,
             long elapsedRealtimeMs, long uptimeMs) {
@@ -6633,15 +6346,6 @@
         }
     }
 
-    /**
-     * Telephony stack updates the phone state.
-     * @param state phone state from ServiceState.getState()
-     */
-    @GuardedBy("this")
-    public void notePhoneStateLocked(int state, int simState) {
-        notePhoneStateLocked(state, simState, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
     @GuardedBy("this")
     public void notePhoneStateLocked(int state, int simState,
             long elapsedRealtimeMs, long uptimeMs) {
@@ -6650,12 +6354,6 @@
     }
 
     @GuardedBy("this")
-    public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
-        notePhoneSignalStrengthLocked(signalStrength,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void notePhoneSignalStrengthLocked(SignalStrength signalStrength,
             long elapsedRealtimeMs, long uptimeMs) {
         final int overallSignalStrength = signalStrength.getLevel();
@@ -6843,11 +6541,6 @@
     }
 
     @GuardedBy("this")
-    public void noteWifiOnLocked() {
-        noteWifiOnLocked(mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (!mWifiOn) {
             mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG;
@@ -6861,11 +6554,6 @@
     }
 
     @GuardedBy("this")
-    public void noteWifiOffLocked() {
-        noteWifiOffLocked(mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (mWifiOn) {
             mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG;
@@ -6879,11 +6567,6 @@
     }
 
     @GuardedBy("this")
-    public void noteAudioOnLocked(int uid) {
-        noteAudioOnLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
         if (mAudioOnNesting == 0) {
@@ -6899,11 +6582,6 @@
     }
 
     @GuardedBy("this")
-    public void noteAudioOffLocked(int uid) {
-        noteAudioOffLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         if (mAudioOnNesting == 0) {
             return;
@@ -6921,11 +6599,6 @@
     }
 
     @GuardedBy("this")
-    public void noteVideoOnLocked(int uid) {
-        noteVideoOnLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
         if (mVideoOnNesting == 0) {
@@ -6941,11 +6614,6 @@
     }
 
     @GuardedBy("this")
-    public void noteVideoOffLocked(int uid) {
-        noteVideoOffLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         if (mVideoOnNesting == 0) {
             return;
@@ -6963,11 +6631,6 @@
     }
 
     @GuardedBy("this")
-    public void noteResetAudioLocked() {
-        noteResetAudioLocked(mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (mAudioOnNesting > 0) {
             mAudioOnNesting = 0;
@@ -6984,11 +6647,6 @@
     }
 
     @GuardedBy("this")
-    public void noteResetVideoLocked() {
-        noteResetVideoLocked(mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (mVideoOnNesting > 0) {
             mVideoOnNesting = 0;
@@ -7029,12 +6687,6 @@
     }
 
     @GuardedBy("this")
-    public void noteVibratorOnLocked(int uid, long durationMillis) {
-        noteVibratorOnLocked(uid, durationMillis,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteVibratorOnLocked(int uid, long durationMillis,
             long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
@@ -7043,11 +6695,6 @@
     }
 
     @GuardedBy("this")
-    public void noteVibratorOffLocked(int uid) {
-        noteVibratorOffLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
         getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -7055,11 +6702,6 @@
     }
 
     @GuardedBy("this")
-    public void noteFlashlightOnLocked(int uid) {
-        noteFlashlightOnLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
         if (mFlashlightOnNesting++ == 0) {
@@ -7074,11 +6716,6 @@
     }
 
     @GuardedBy("this")
-    public void noteFlashlightOffLocked(int uid) {
-        noteFlashlightOffLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         if (mFlashlightOnNesting == 0) {
             return;
@@ -7096,11 +6733,6 @@
     }
 
     @GuardedBy("this")
-    public void noteCameraOnLocked(int uid) {
-        noteCameraOnLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
         if (mCameraOnNesting++ == 0) {
@@ -7115,11 +6747,6 @@
     }
 
     @GuardedBy("this")
-    public void noteCameraOffLocked(int uid) {
-        noteCameraOffLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         if (mCameraOnNesting == 0) {
             return;
@@ -7137,11 +6764,6 @@
     }
 
     @GuardedBy("this")
-    public void noteResetCameraLocked() {
-        noteResetCameraLocked(mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (mCameraOnNesting > 0) {
             mCameraOnNesting = 0;
@@ -7158,11 +6780,6 @@
     }
 
     @GuardedBy("this")
-    public void noteResetFlashlightLocked() {
-        noteResetFlashlightLocked(mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (mFlashlightOnNesting > 0) {
             mFlashlightOnNesting = 0;
@@ -7265,11 +6882,6 @@
     }
 
     @GuardedBy("this")
-    public void noteResetBluetoothScanLocked() {
-        noteResetBluetoothScanLocked(mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (mBluetoothScanNesting > 0) {
             mBluetoothScanNesting = 0;
@@ -7322,12 +6934,6 @@
     }
 
     @GuardedBy("this")
-    public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid) {
-        noteWifiRadioPowerState(powerState, timestampNs, uid,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid,
             long elapsedRealtimeMs, long uptimeMs) {
         if (mWifiRadioPowerState != powerState) {
@@ -7352,11 +6958,6 @@
     }
 
     @GuardedBy("this")
-    public void noteWifiRunningLocked(WorkSource ws) {
-        noteWifiRunningLocked(ws, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) {
         if (!mGlobalWifiRunning) {
             mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG;
@@ -7388,12 +6989,6 @@
     }
 
     @GuardedBy("this")
-    public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
-        noteWifiRunningChangedLocked(oldWs, newWs,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs,
             long elapsedRealtimeMs, long uptimeMs) {
         if (mGlobalWifiRunning) {
@@ -7434,11 +7029,6 @@
     }
 
     @GuardedBy("this")
-    public void noteWifiStoppedLocked(WorkSource ws) {
-        noteWifiStoppedLocked(ws, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) {
         if (mGlobalWifiRunning) {
             mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG;
@@ -7470,11 +7060,6 @@
     }
 
     @GuardedBy("this")
-    public void noteWifiStateLocked(int wifiState, String accessPoint) {
-        noteWifiStateLocked(wifiState, accessPoint, mClock.elapsedRealtime());
-    }
-
-    @GuardedBy("this")
     public void noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs) {
         if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState);
         if (mWifiState != wifiState) {
@@ -7488,12 +7073,6 @@
     }
 
     @GuardedBy("this")
-    public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) {
-        noteWifiSupplicantStateChangedLocked(supplState, failedAuth,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth,
             long elapsedRealtimeMs, long uptimeMs) {
         if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState);
@@ -7525,11 +7104,6 @@
     }
 
     @GuardedBy("this")
-    public void noteWifiRssiChangedLocked(int newRssi) {
-        noteWifiRssiChangedLocked(newRssi, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs) {
         int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS);
         if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin);
@@ -7555,12 +7129,7 @@
         }
     }
 
-    int mWifiFullLockNesting = 0;
-
-    @GuardedBy("this")
-    public void noteFullWifiLockAcquiredLocked(int uid) {
-        noteFullWifiLockAcquiredLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
+    private int mWifiFullLockNesting = 0;
 
     @GuardedBy("this")
     public void noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
@@ -7576,11 +7145,6 @@
     }
 
     @GuardedBy("this")
-    public void noteFullWifiLockReleasedLocked(int uid) {
-        noteFullWifiLockReleasedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         mWifiFullLockNesting--;
         if (mWifiFullLockNesting == 0) {
@@ -7631,11 +7195,6 @@
                 .noteWifiScanStoppedLocked(elapsedRealtimeMs);
     }
 
-    public void noteWifiBatchedScanStartedLocked(int uid, int csph) {
-        noteWifiBatchedScanStartedLocked(uid, csph,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
     public void noteWifiBatchedScanStartedLocked(int uid, int csph,
             long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
@@ -7643,22 +7202,13 @@
                 .noteWifiBatchedScanStartedLocked(csph, elapsedRealtimeMs);
     }
 
-    public void noteWifiBatchedScanStoppedLocked(int uid) {
-        noteWifiBatchedScanStoppedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
     public void noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
         getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
                 .noteWifiBatchedScanStoppedLocked(elapsedRealtimeMs);
     }
 
-    int mWifiMulticastNesting = 0;
-
-    @GuardedBy("this")
-    public void noteWifiMulticastEnabledLocked(int uid) {
-        noteWifiMulticastEnabledLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
+    private int mWifiMulticastNesting = 0;
 
     @GuardedBy("this")
     public void noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
@@ -7681,11 +7231,6 @@
     }
 
     @GuardedBy("this")
-    public void noteWifiMulticastDisabledLocked(int uid) {
-        noteWifiMulticastDisabledLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
         mWifiMulticastNesting--;
@@ -7706,12 +7251,6 @@
     }
 
     @GuardedBy("this")
-    public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
-        noteFullWifiLockAcquiredFromSourceLocked(ws,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws,
             long elapsedRealtimeMs, long uptimeMs) {
         int N = ws.size();
@@ -7731,12 +7270,6 @@
     }
 
     @GuardedBy("this")
-    public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
-        noteFullWifiLockReleasedFromSourceLocked(ws,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws,
             long elapsedRealtimeMs, long uptimeMs) {
         int N = ws.size();
@@ -7756,11 +7289,6 @@
     }
 
     @GuardedBy("this")
-    public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
-        noteWifiScanStartedFromSourceLocked(ws, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteWifiScanStartedFromSourceLocked(WorkSource ws,
             long elapsedRealtimeMs, long uptimeMs) {
         int N = ws.size();
@@ -7780,11 +7308,6 @@
     }
 
     @GuardedBy("this")
-    public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
-        noteWifiScanStoppedFromSourceLocked(ws, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteWifiScanStoppedFromSourceLocked(WorkSource ws,
             long elapsedRealtimeMs, long uptimeMs) {
         int N = ws.size();
@@ -7804,12 +7327,6 @@
     }
 
     @GuardedBy("this")
-    public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) {
-        noteWifiBatchedScanStartedFromSourceLocked(ws, csph,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph,
             long elapsedRealtimeMs, long uptimeMs) {
         int N = ws.size();
@@ -7827,12 +7344,6 @@
     }
 
     @GuardedBy("this")
-    public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) {
-        noteWifiBatchedScanStoppedFromSourceLocked(ws,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    @GuardedBy("this")
     public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws,
             long elapsedRealtimeMs, long uptimeMs) {
         int N = ws.size();
@@ -8587,10 +8098,6 @@
      */
     @VisibleForTesting
     protected static class BinderCallStats {
-        static final Comparator<BinderCallStats> COMPARATOR =
-                Comparator.comparing(BinderCallStats::getClassName)
-                        .thenComparing(BinderCallStats::getMethodName);
-
         public Class<? extends Binder> binderClass;
         public int transactionCode;
         public String methodName;
@@ -8846,10 +8353,6 @@
          */
         private double mProportionalSystemServiceUsage;
 
-        public Uid(BatteryStatsImpl bsi, int uid) {
-            this(bsi, uid, bsi.mClock.elapsedRealtime(), bsi.mClock.uptimeMillis());
-        }
-
         public Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs) {
             mBsi = bsi;
             mUid = uid;
@@ -9707,12 +9210,12 @@
         }
 
         public void noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs) {
-            createVibratorOnTimerLocked().addDuration(mBsi, durationMillis, elapsedRealtimeMs);
+            createVibratorOnTimerLocked().addDuration(durationMillis, elapsedRealtimeMs);
         }
 
         public void noteVibratorOffLocked(long elapsedRealtimeMs) {
             if (mVibratorOnTimer != null) {
-                mVibratorOnTimer.abortLastDuration(mBsi, elapsedRealtimeMs);
+                mVibratorOnTimer.abortLastDuration(elapsedRealtimeMs);
             }
         }
 
@@ -10464,281 +9967,6 @@
             }
         }
 
-        void writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs) {
-            mOnBatteryBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs);
-            mOnBatteryScreenOffBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs);
-
-            final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
-            int NW = wakeStats.size();
-            out.writeInt(NW);
-            for (int iw=0; iw<NW; iw++) {
-                out.writeString(wakeStats.keyAt(iw));
-                Uid.Wakelock wakelock = wakeStats.valueAt(iw);
-                wakelock.writeToParcelLocked(out, elapsedRealtimeUs);
-            }
-
-            final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap();
-            int NS = syncStats.size();
-            out.writeInt(NS);
-            for (int is=0; is<NS; is++) {
-                out.writeString(syncStats.keyAt(is));
-                DualTimer timer = syncStats.valueAt(is);
-                Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
-            }
-
-            final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap();
-            int NJ = jobStats.size();
-            out.writeInt(NJ);
-            for (int ij=0; ij<NJ; ij++) {
-                out.writeString(jobStats.keyAt(ij));
-                DualTimer timer = jobStats.valueAt(ij);
-                Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
-            }
-
-            writeJobCompletionsToParcelLocked(out);
-
-            mJobsDeferredEventCount.writeToParcel(out);
-            mJobsDeferredCount.writeToParcel(out);
-            mJobsFreshnessTimeMs.writeToParcel(out);
-            for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) {
-                Counter.writeCounterToParcel(out, mJobsFreshnessBuckets[i]);
-            }
-
-            int NSE = mSensorStats.size();
-            out.writeInt(NSE);
-            for (int ise=0; ise<NSE; ise++) {
-                out.writeInt(mSensorStats.keyAt(ise));
-                Uid.Sensor sensor = mSensorStats.valueAt(ise);
-                sensor.writeToParcelLocked(out, elapsedRealtimeUs);
-            }
-
-            int NP = mProcessStats.size();
-            out.writeInt(NP);
-            for (int ip=0; ip<NP; ip++) {
-                out.writeString(mProcessStats.keyAt(ip));
-                Uid.Proc proc = mProcessStats.valueAt(ip);
-                proc.writeToParcelLocked(out);
-            }
-
-            out.writeInt(mPackageStats.size());
-            for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
-                out.writeString(pkgEntry.getKey());
-                Uid.Pkg pkg = pkgEntry.getValue();
-                pkg.writeToParcelLocked(out);
-            }
-
-            if (mWifiRunningTimer != null) {
-                out.writeInt(1);
-                mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs);
-            } else {
-                out.writeInt(0);
-            }
-            if (mFullWifiLockTimer != null) {
-                out.writeInt(1);
-                mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs);
-            } else {
-                out.writeInt(0);
-            }
-            if (mWifiScanTimer != null) {
-                out.writeInt(1);
-                mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs);
-            } else {
-                out.writeInt(0);
-            }
-            for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
-                if (mWifiBatchedScanTimer[i] != null) {
-                    out.writeInt(1);
-                    mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs);
-                } else {
-                    out.writeInt(0);
-                }
-            }
-            if (mWifiMulticastTimer != null) {
-                out.writeInt(1);
-                mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs);
-            } else {
-                out.writeInt(0);
-            }
-
-            if (mAudioTurnedOnTimer != null) {
-                out.writeInt(1);
-                mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
-            } else {
-                out.writeInt(0);
-            }
-            if (mVideoTurnedOnTimer != null) {
-                out.writeInt(1);
-                mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
-            } else {
-                out.writeInt(0);
-            }
-            if (mFlashlightTurnedOnTimer != null) {
-                out.writeInt(1);
-                mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
-            } else {
-                out.writeInt(0);
-            }
-            if (mCameraTurnedOnTimer != null) {
-                out.writeInt(1);
-                mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
-            } else {
-                out.writeInt(0);
-            }
-            if (mForegroundActivityTimer != null) {
-                out.writeInt(1);
-                mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs);
-            } else {
-                out.writeInt(0);
-            }
-            if (mForegroundServiceTimer != null) {
-                out.writeInt(1);
-                mForegroundServiceTimer.writeToParcel(out, elapsedRealtimeUs);
-            } else {
-                out.writeInt(0);
-            }
-            if (mAggregatedPartialWakelockTimer != null) {
-                out.writeInt(1);
-                mAggregatedPartialWakelockTimer.writeToParcel(out, elapsedRealtimeUs);
-            } else {
-                out.writeInt(0);
-            }
-            if (mBluetoothScanTimer != null) {
-                out.writeInt(1);
-                mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs);
-            } else {
-                out.writeInt(0);
-            }
-            if (mBluetoothUnoptimizedScanTimer != null) {
-                out.writeInt(1);
-                mBluetoothUnoptimizedScanTimer.writeToParcel(out, elapsedRealtimeUs);
-            } else {
-                out.writeInt(0);
-            }
-            if (mBluetoothScanResultCounter != null) {
-                out.writeInt(1);
-                mBluetoothScanResultCounter.writeToParcel(out);
-            } else {
-                out.writeInt(0);
-            }
-            if (mBluetoothScanResultBgCounter != null) {
-                out.writeInt(1);
-                mBluetoothScanResultBgCounter.writeToParcel(out);
-            } else {
-                out.writeInt(0);
-            }
-            for (int i = 0; i < NUM_PROCESS_STATE; i++) {
-                if (mProcessStateTimer[i] != null) {
-                    out.writeInt(1);
-                    mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs);
-                } else {
-                    out.writeInt(0);
-                }
-            }
-            if (mVibratorOnTimer != null) {
-                out.writeInt(1);
-                mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs);
-            } else {
-                out.writeInt(0);
-            }
-            if (mUserActivityCounters != null) {
-                out.writeInt(1);
-                for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
-                    mUserActivityCounters[i].writeToParcel(out);
-                }
-            } else {
-                out.writeInt(0);
-            }
-            if (mNetworkByteActivityCounters != null) {
-                out.writeInt(1);
-                for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
-                    mNetworkByteActivityCounters[i].writeToParcel(out);
-                    mNetworkPacketActivityCounters[i].writeToParcel(out);
-                }
-                if (mMobileRadioActiveTime != null) {
-                    out.writeBoolean(true);
-                    mMobileRadioActiveTime.writeToParcel(out);
-                } else {
-                    out.writeBoolean(false);
-                }
-                mMobileRadioActiveCount.writeToParcel(out);
-            } else {
-                out.writeInt(0);
-            }
-
-            if (mWifiControllerActivity != null) {
-                out.writeInt(1);
-                mWifiControllerActivity.writeToParcel(out, 0);
-            } else {
-                out.writeInt(0);
-            }
-
-            if (mBluetoothControllerActivity != null) {
-                out.writeInt(1);
-                mBluetoothControllerActivity.writeToParcel(out, 0);
-            } else {
-                out.writeInt(0);
-            }
-
-            if (mModemControllerActivity != null) {
-                out.writeInt(1);
-                mModemControllerActivity.writeToParcel(out, 0);
-            } else {
-                out.writeInt(0);
-            }
-
-            if (mUidMeasuredEnergyStats != null) {
-                out.writeInt(1);
-                mUidMeasuredEnergyStats.writeToParcel(out);
-            } else {
-                out.writeInt(0);
-            }
-
-            mUserCpuTime.writeToParcel(out);
-            mSystemCpuTime.writeToParcel(out);
-
-            mBsi.writeCpuSpeedCountersToParcel(out, mCpuClusterSpeedTimesUs);
-
-            LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs);
-            LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs);
-
-            if (mCpuActiveTimeMs != null) {
-                out.writeInt(mCpuActiveTimeMs.getStateCount());
-                mCpuActiveTimeMs.writeToParcel(out);
-            } else {
-                out.writeInt(0);
-            }
-
-            mCpuClusterTimesMs.writeToParcel(out);
-
-            if (mProcStateTimeMs != null) {
-                out.writeInt(mProcStateTimeMs.getStateCount());
-                mProcStateTimeMs.writeToParcel(out);
-            } else {
-                out.writeInt(0);
-            }
-            if (mProcStateScreenOffTimeMs != null) {
-                out.writeInt(mProcStateScreenOffTimeMs.getStateCount());
-                mProcStateScreenOffTimeMs.writeToParcel(out);
-            } else {
-                out.writeInt(0);
-            }
-
-            if (mMobileRadioApWakeupCount != null) {
-                out.writeInt(1);
-                mMobileRadioApWakeupCount.writeToParcel(out);
-            } else {
-                out.writeInt(0);
-            }
-
-            if (mWifiRadioApWakeupCount != null) {
-                out.writeInt(1);
-                mWifiRadioApWakeupCount.writeToParcel(out);
-            } else {
-                out.writeInt(0);
-            }
-            out.writeDouble(mProportionalSystemServiceUsage);
-        }
-
         void readJobCompletionsFromParcelLocked(Parcel in) {
             int numJobCompletions = in.readInt();
             mJobCompletions.clear();
@@ -10757,306 +9985,6 @@
             }
         }
 
-        @GuardedBy("mBsi")
-        void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
-            final long timestampMs = mBsi.mClock.elapsedRealtime();
-            mOnBatteryBackgroundTimeBase.readFromParcel(in);
-            mOnBatteryScreenOffBackgroundTimeBase.readFromParcel(in);
-
-            int numWakelocks = in.readInt();
-            mWakelockStats.clear();
-            for (int j = 0; j < numWakelocks; j++) {
-                String wakelockName = in.readString();
-                Uid.Wakelock wakelock = new Wakelock(mBsi, this);
-                wakelock.readFromParcelLocked(
-                        timeBase, screenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, in);
-                mWakelockStats.add(wakelockName, wakelock);
-            }
-
-            int numSyncs = in.readInt();
-            mSyncStats.clear();
-            for (int j = 0; j < numSyncs; j++) {
-                String syncName = in.readString();
-                if (in.readInt() != 0) {
-                    mSyncStats.add(syncName, new DualTimer(mBsi.mClock, Uid.this, SYNC, null,
-                            mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in));
-                }
-            }
-
-            int numJobs = in.readInt();
-            mJobStats.clear();
-            for (int j = 0; j < numJobs; j++) {
-                String jobName = in.readString();
-                if (in.readInt() != 0) {
-                    mJobStats.add(jobName, new DualTimer(mBsi.mClock, Uid.this, JOB, null,
-                            mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in));
-                }
-            }
-
-            readJobCompletionsFromParcelLocked(in);
-
-            mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase, in);
-            mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase, in);
-            mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
-            for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) {
-                mJobsFreshnessBuckets[i] = Counter.readCounterFromParcel(mBsi.mOnBatteryTimeBase,
-                        in);
-            }
-
-            int numSensors = in.readInt();
-            mSensorStats.clear();
-            for (int k = 0; k < numSensors; k++) {
-                int sensorNumber = in.readInt();
-                Uid.Sensor sensor = new Sensor(mBsi, this, sensorNumber);
-                sensor.readFromParcelLocked(mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase,
-                        in);
-                mSensorStats.put(sensorNumber, sensor);
-            }
-
-            int numProcs = in.readInt();
-            mProcessStats.clear();
-            for (int k = 0; k < numProcs; k++) {
-                String processName = in.readString();
-                Uid.Proc proc = new Proc(mBsi, processName);
-                proc.readFromParcelLocked(in);
-                mProcessStats.put(processName, proc);
-            }
-
-            int numPkgs = in.readInt();
-            mPackageStats.clear();
-            for (int l = 0; l < numPkgs; l++) {
-                String packageName = in.readString();
-                Uid.Pkg pkg = new Pkg(mBsi);
-                pkg.readFromParcelLocked(in);
-                mPackageStats.put(packageName, pkg);
-            }
-
-            mWifiRunning = false;
-            if (in.readInt() != 0) {
-                mWifiRunningTimer = new StopwatchTimer(mBsi.mClock, Uid.this, WIFI_RUNNING,
-                        mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase, in);
-            } else {
-                mWifiRunningTimer = null;
-            }
-            mFullWifiLockOut = false;
-            if (in.readInt() != 0) {
-                mFullWifiLockTimer = new StopwatchTimer(mBsi.mClock, Uid.this, FULL_WIFI_LOCK,
-                        mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase, in);
-            } else {
-                mFullWifiLockTimer = null;
-            }
-            mWifiScanStarted = false;
-            if (in.readInt() != 0) {
-                mWifiScanTimer = new DualTimer(mBsi.mClock, Uid.this, WIFI_SCAN,
-                        mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase,
-                        in);
-            } else {
-                mWifiScanTimer = null;
-            }
-            mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
-            for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
-                if (in.readInt() != 0) {
-                    makeWifiBatchedScanBin(i, in);
-                } else {
-                    mWifiBatchedScanTimer[i] = null;
-                }
-            }
-            mWifiMulticastWakelockCount = 0;
-            if (in.readInt() != 0) {
-                mWifiMulticastTimer = new StopwatchTimer(mBsi.mClock, Uid.this,
-                        WIFI_MULTICAST_ENABLED,
-                        mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase, in);
-            } else {
-                mWifiMulticastTimer = null;
-            }
-            if (in.readInt() != 0) {
-                mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, AUDIO_TURNED_ON,
-                        mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase, in);
-            } else {
-                mAudioTurnedOnTimer = null;
-            }
-            if (in.readInt() != 0) {
-                mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, VIDEO_TURNED_ON,
-                        mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase, in);
-            } else {
-                mVideoTurnedOnTimer = null;
-            }
-            if (in.readInt() != 0) {
-                mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this,
-                        FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase, in);
-            } else {
-                mFlashlightTurnedOnTimer = null;
-            }
-            if (in.readInt() != 0) {
-                mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, CAMERA_TURNED_ON,
-                        mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase, in);
-            } else {
-                mCameraTurnedOnTimer = null;
-            }
-            if (in.readInt() != 0) {
-                mForegroundActivityTimer = new StopwatchTimer(mBsi.mClock, Uid.this,
-                        FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase, in);
-            } else {
-                mForegroundActivityTimer = null;
-            }
-            if (in.readInt() != 0) {
-                mForegroundServiceTimer = new StopwatchTimer(mBsi.mClock, Uid.this,
-                        FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase, in);
-            } else {
-                mForegroundServiceTimer = null;
-            }
-            if (in.readInt() != 0) {
-                mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClock, this,
-                        AGGREGATED_WAKE_TYPE_PARTIAL, null,
-                        mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase,
-                        in);
-            } else {
-                mAggregatedPartialWakelockTimer = null;
-            }
-            if (in.readInt() != 0) {
-                mBluetoothScanTimer = new DualTimer(mBsi.mClock, Uid.this, BLUETOOTH_SCAN_ON,
-                        mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase,
-                        mOnBatteryBackgroundTimeBase, in);
-            } else {
-                mBluetoothScanTimer = null;
-            }
-            if (in.readInt() != 0) {
-                mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClock, Uid.this,
-                        BLUETOOTH_UNOPTIMIZED_SCAN_ON, null,
-                        mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in);
-            } else {
-                mBluetoothUnoptimizedScanTimer = null;
-            }
-            if (in.readInt() != 0) {
-                mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase, in);
-            } else {
-                mBluetoothScanResultCounter = null;
-            }
-            if (in.readInt() != 0) {
-                mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase, in);
-            } else {
-                mBluetoothScanResultBgCounter = null;
-            }
-            mProcessState = Uid.PROCESS_STATE_NONEXISTENT;
-            for (int i = 0; i < NUM_PROCESS_STATE; i++) {
-                if (in.readInt() != 0) {
-                    makeProcessState(i, in);
-                } else {
-                    mProcessStateTimer[i] = null;
-                }
-            }
-            if (in.readInt() != 0) {
-                mVibratorOnTimer = new BatchTimer(mBsi.mClock, Uid.this, VIBRATOR_ON,
-                        mBsi.mOnBatteryTimeBase, in);
-            } else {
-                mVibratorOnTimer = null;
-            }
-            if (in.readInt() != 0) {
-                mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
-                for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
-                    mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase, in);
-                }
-            } else {
-                mUserActivityCounters = null;
-            }
-            if (in.readInt() != 0) {
-                mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
-                mNetworkPacketActivityCounters
-                        = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
-                for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
-                    mNetworkByteActivityCounters[i]
-                            = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
-                    mNetworkPacketActivityCounters[i]
-                            = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
-                }
-                if (in.readBoolean()) {
-                    mMobileRadioActiveTime = TimeMultiStateCounter.readFromParcel(in,
-                            mBsi.mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT,
-                            timestampMs);
-                }
-
-                mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
-            } else {
-                mNetworkByteActivityCounters = null;
-                mNetworkPacketActivityCounters = null;
-            }
-
-            if (in.readInt() != 0) {
-                mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock,
-                        mBsi.mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS, in);
-            } else {
-                mWifiControllerActivity = null;
-            }
-
-            if (in.readInt() != 0) {
-                mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock,
-                        mBsi.mOnBatteryTimeBase, NUM_BT_TX_LEVELS, in);
-            } else {
-                mBluetoothControllerActivity = null;
-            }
-
-            if (in.readInt() != 0) {
-                mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock,
-                        mBsi.mOnBatteryTimeBase, ModemActivityInfo.getNumTxPowerLevels(), in);
-            } else {
-                mModemControllerActivity = null;
-            }
-
-            if (in.readInt() != 0) {
-                mUidMeasuredEnergyStats = new MeasuredEnergyStats(mBsi.mMeasuredEnergyStatsConfig,
-                        in);
-            }
-
-            mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
-            mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
-
-            mCpuClusterSpeedTimesUs = mBsi.readCpuSpeedCountersFromParcel(in);
-
-            mCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(in, mBsi.mOnBatteryTimeBase);
-            mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(
-                    in, mBsi.mOnBatteryScreenOffTimeBase);
-
-            int stateCount = in.readInt();
-            if (stateCount != 0) {
-                mCpuActiveTimeMs = TimeMultiStateCounter.readFromParcel(in,
-                        mBsi.mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT,
-                        timestampMs);
-            }
-            mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in);
-
-            stateCount = in.readInt();
-            if (stateCount != 0) {
-                mProcStateTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in,
-                        mBsi.mOnBatteryTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT,
-                        mBsi.getCpuFreqCount(), mBsi.mClock.elapsedRealtime());
-            } else {
-                mProcStateTimeMs = null;
-            }
-
-            stateCount = in.readInt();
-            if (stateCount != 0) {
-                mProcStateScreenOffTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in,
-                        mBsi.mOnBatteryScreenOffTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT,
-                        mBsi.getCpuFreqCount(), mBsi.mClock.elapsedRealtime());
-            } else {
-                mProcStateScreenOffTimeMs = null;
-            }
-
-            if (in.readInt() != 0) {
-                mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
-            } else {
-                mMobileRadioApWakeupCount = null;
-            }
-
-            if (in.readInt() != 0) {
-                mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
-            } else {
-                mWifiRadioApWakeupCount = null;
-            }
-
-            mProportionalSystemServiceUsage = in.readDouble();
-        }
-
         public void noteJobsDeferredLocked(int numDeferred, long sinceLast) {
             mJobsDeferredEventCount.addAtomic(1);
             mJobsDeferredCount.addAtomic(numDeferred);
@@ -12261,10 +11189,6 @@
         public void noteStopGps(long elapsedRealtimeMs) {
             noteStopSensor(Sensor.GPS, elapsedRealtimeMs);
         }
-
-        public BatteryStatsImpl getBatteryStats() {
-            return mBsi;
-        }
     }
 
     @GuardedBy("this")
@@ -12418,32 +11342,12 @@
         mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase);
         mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase);
         mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase);
-        mDischargeStartLevel = 0;
         mDischargeUnplugLevel = 0;
         mDischargePlugLevel = -1;
         mDischargeCurrentLevel = 0;
         mCurrentBatteryLevel = 0;
     }
 
-    public BatteryStatsImpl(Parcel p) {
-        this(Clock.SYSTEM_CLOCK, p);
-    }
-
-    public BatteryStatsImpl(Clock clock, Parcel p) {
-        init(clock);
-        mStatsFile = null;
-        mCheckinFile = null;
-        mDailyFile = null;
-        mHandler = null;
-        mExternalSync = null;
-        mConstants = new Constants(mHandler);
-        clearHistoryLocked();
-        mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer);
-        readFromParcel(p);
-        mPlatformIdleStateCallback = null;
-        mMeasuredEnergyRetriever = null;
-    }
-
     public void setPowerProfileLocked(PowerProfile profile) {
         mPowerProfile = profile;
 
@@ -12948,7 +11852,6 @@
         long mSecRealtime = mClock.elapsedRealtime();
         long realtimeUs = mSecRealtime * 1000;
         resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_ADB_COMMAND);
-        mDischargeStartLevel = mHistoryCur.batteryLevel;
         pullPendingStateUpdatesLocked();
         addHistoryRecordLocked(mSecRealtime, mSecUptime);
         mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel
@@ -14654,13 +13557,6 @@
     /**
      * Read and distribute kernel wake lock use across apps.
      */
-    public void updateKernelWakelocksLocked() {
-        updateKernelWakelocksLocked(mClock.elapsedRealtime() * 1000);
-    }
-
-    /**
-     * @see #updateKernelWakelocksLocked()
-     */
     public void updateKernelWakelocksLocked(long elapsedRealtimeUs) {
         final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats(
                 mTmpWakelockStats);
@@ -14717,10 +13613,6 @@
     /**
      * Reads the newest memory stats from the kernel.
      */
-    public void updateKernelMemoryBandwidthLocked() {
-        updateKernelMemoryBandwidthLocked(mClock.elapsedRealtime() * 1000);
-    }
-
     public void updateKernelMemoryBandwidthLocked(long elapsedRealtimeUs) {
         mKernelMemoryBandwidthStats.updateStats();
         LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries();
@@ -15496,14 +14388,12 @@
                     // Only use the reported coulomb charge value if it is supported and reported.
                     mEstimatedBatteryCapacityMah = (int) ((chargeUah / 1000) / (level / 100.0));
                 }
-                mDischargeStartLevel = level;
                 reset = true;
                 mDischargeStepTracker.init();
             }
             if (mCharging) {
                 setChargingLocked(false);
             }
-            mLastChargingStateLevel = level;
             mOnBattery = mOnBatteryInternal = true;
             mLastDischargeStepLevel = level;
             mMinDischargeStepLevel = level;
@@ -15540,7 +14430,6 @@
             mDischargeAmountScreenOff = 0;
             updateTimeBasesLocked(true, screenState, uptimeUs, realtimeUs);
         } else {
-            mLastChargingStateLevel = level;
             mOnBattery = mOnBatteryInternal = false;
             pullPendingStateUpdatesLocked();
             mHistoryCur.batteryLevel = (byte)level;
@@ -15613,15 +14502,6 @@
     @GuardedBy("this")
     public void setBatteryStateLocked(final int status, final int health, final int plugType,
             final int level, /* not final */ int temp, final int voltageMv, final int chargeUah,
-            final int chargeFullUah, final long chargeTimeToFullSeconds) {
-        setBatteryStateLocked(status, health, plugType, level, temp, voltageMv, chargeUah,
-                chargeFullUah, chargeTimeToFullSeconds,
-                mClock.elapsedRealtime(), mClock.uptimeMillis(), mClock.currentTimeMillis());
-    }
-
-    @GuardedBy("this")
-    public void setBatteryStateLocked(final int status, final int health, final int plugType,
-            final int level, /* not final */ int temp, final int voltageMv, final int chargeUah,
             final int chargeFullUah, final long chargeTimeToFullSeconds,
             final long elapsedRealtimeMs, final long uptimeMs, final long currentTimeMs) {
         // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0.
@@ -15651,7 +14531,6 @@
             mHistoryCur.batteryChargeUah = chargeUah;
             mMaxChargeStepLevel = mMinDischargeStepLevel =
                     mLastChargeStepLevel = mLastDischargeStepLevel = level;
-            mLastChargingStateLevel = level;
         } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) {
             recordDailyStatsIfNeededLocked(level >= 100 && onBattery, currentTimeMs);
         }
@@ -15890,44 +14769,6 @@
         return mOnBatteryScreenOffTimeBase.computeRealtime(curTimeUs, which);
     }
 
-    private long computeTimePerLevel(long[] steps, int numSteps) {
-        // For now we'll do a simple average across all steps.
-        if (numSteps <= 0) {
-            return -1;
-        }
-        long total = 0;
-        for (int i=0; i<numSteps; i++) {
-            total += steps[i] & STEP_LEVEL_TIME_MASK;
-        }
-        return total / numSteps;
-        /*
-        long[] buckets = new long[numSteps];
-        int numBuckets = 0;
-        int numToAverage = 4;
-        int i = 0;
-        while (i < numSteps) {
-            long totalTime = 0;
-            int num = 0;
-            for (int j=0; j<numToAverage && (i+j)<numSteps; j++) {
-                totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK;
-                num++;
-            }
-            buckets[numBuckets] = totalTime / num;
-            numBuckets++;
-            numToAverage *= 2;
-            i += num;
-        }
-        if (numBuckets < 1) {
-            return -1;
-        }
-        long averageTime = buckets[numBuckets-1];
-        for (i=numBuckets-2; i>=0; i--) {
-            averageTime = (averageTime + buckets[i]) / 2;
-        }
-        return averageTime;
-        */
-    }
-
     @Override
     public long computeBatteryTimeRemaining(long curTime) {
         if (!mOnBattery) {
@@ -16103,13 +14944,6 @@
     /**
      * @return battery uptime in microseconds
      */
-    protected long getBatteryUptimeLocked() {
-        return getBatteryUptimeLocked(mClock.uptimeMillis());
-    }
-
-    /**
-     * @return battery uptime in microseconds
-     */
     protected long getBatteryUptimeLocked(long uptimeMs) {
         return mOnBatteryTimeBase.getUptime(uptimeMs * 1000);
     }
@@ -16334,14 +15168,6 @@
     }
 
     /**
-     * Remove the statistics object for a particular uid.
-     */
-    @GuardedBy("this")
-    public void removeUidStatsLocked(int uid) {
-        removeUidStatsLocked(uid, mClock.elapsedRealtime());
-    }
-
-    /**
      * @see #removeUidStatsLocked(int)
      */
     @GuardedBy("this")
@@ -16391,13 +15217,6 @@
      * Retrieve the statistics object for a particular process, creating
      * if needed.
      */
-    public Uid.Proc getProcessStatsLocked(int uid, String name) {
-        return getProcessStatsLocked(uid, name, mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
-    /**
-     * @see #getProcessStatsLocked(int, String)
-     */
     public Uid.Proc getProcessStatsLocked(int uid, String name,
             long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
@@ -16427,11 +15246,6 @@
      * Retrieve the statistics object for a particular service, creating
      * if needed.
      */
-    public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
-        return getServiceStatsLocked(uid, pkg, name,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
-    }
-
     public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name,
             long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
@@ -16542,8 +15356,6 @@
     public final class Constants extends ContentObserver {
         public static final String KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME
                 = "track_cpu_active_cluster_time";
-        public static final String KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS
-                = "proc_state_cpu_times_read_delay_ms";
         public static final String KEY_KERNEL_UID_READERS_THROTTLE_TIME
                 = "kernel_uid_readers_throttle_time";
         public static final String KEY_UID_REMOVE_DELAY_MS
@@ -17014,10 +15826,6 @@
         recordDailyStatsIfNeededLocked(false, mClock.currentTimeMillis());
     }
 
-    public int describeContents() {
-        return 0;
-    }
-
     @GuardedBy("this")
     void  readHistoryBuffer(Parcel in) throws ParcelFormatException {
         final int version = in.readInt();
@@ -18183,530 +16991,6 @@
     }
 
     @GuardedBy("this")
-    public void readFromParcel(Parcel in) {
-        readFromParcelLocked(in);
-    }
-
-    @GuardedBy("this")
-    @SuppressWarnings("GuardedBy")  // errorprone false positive on u.readFromParcelLocked
-    void readFromParcelLocked(Parcel in) {
-        int magic = in.readInt();
-        if (magic != MAGIC) {
-            throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic));
-        }
-
-        readHistoryBuffer(in);
-        mBatteryStatsHistory.readFromParcel(in);
-
-        mStartCount = in.readInt();
-        mStartClockTimeMs = in.readLong();
-        mStartPlatformVersion = in.readString();
-        mEndPlatformVersion = in.readString();
-        mUptimeUs = in.readLong();
-        mUptimeStartUs = in.readLong();
-        mRealtimeUs = in.readLong();
-        mRealtimeStartUs = in.readLong();
-        mOnBattery = in.readInt() != 0;
-        mEstimatedBatteryCapacityMah = in.readInt();
-        mLastLearnedBatteryCapacityUah = in.readInt();
-        mMinLearnedBatteryCapacityUah = in.readInt();
-        mMaxLearnedBatteryCapacityUah = in.readInt();
-        mOnBatteryInternal = false; // we are no longer really running.
-        mOnBatteryTimeBase.readFromParcel(in);
-        mOnBatteryScreenOffTimeBase.readFromParcel(in);
-
-        mScreenState = Display.STATE_UNKNOWN;
-        mScreenOnTimer = new StopwatchTimer(mClock, null, -1, null, mOnBatteryTimeBase, in);
-        mScreenDozeTimer = new StopwatchTimer(mClock, null, -1, null, mOnBatteryTimeBase, in);
-        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
-            mScreenBrightnessTimer[i] = new StopwatchTimer(mClock, null, -100 - i, null,
-                    mOnBatteryTimeBase, in);
-        }
-        mInteractive = false;
-        mInteractiveTimer = new StopwatchTimer(mClock, null, -10, null, mOnBatteryTimeBase, in);
-        mPhoneOn = false;
-        mPowerSaveModeEnabledTimer = new StopwatchTimer(mClock, null, -2, null,
-                mOnBatteryTimeBase, in);
-        mLongestLightIdleTimeMs = in.readLong();
-        mLongestFullIdleTimeMs = in.readLong();
-        mDeviceIdleModeLightTimer = new StopwatchTimer(mClock, null, -14, null,
-                mOnBatteryTimeBase, in);
-        mDeviceIdleModeFullTimer = new StopwatchTimer(mClock, null, -11, null,
-                mOnBatteryTimeBase, in);
-        mDeviceLightIdlingTimer = new StopwatchTimer(mClock, null, -15, null,
-                mOnBatteryTimeBase, in);
-        mDeviceIdlingTimer = new StopwatchTimer(mClock, null, -12, null, mOnBatteryTimeBase, in);
-        mPhoneOnTimer = new StopwatchTimer(mClock, null, -3, null, mOnBatteryTimeBase, in);
-        for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) {
-            mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClock, null, -200 - i,
-                    null, mOnBatteryTimeBase, in);
-        }
-        mPhoneSignalScanningTimer = new StopwatchTimer(mClock, null, -200 + 1, null,
-                mOnBatteryTimeBase, in);
-        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
-            mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClock, null, -300 - i,
-                    null, mOnBatteryTimeBase, in);
-        }
-        for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
-            mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
-            mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
-        }
-        mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
-        mMobileRadioActiveTimer = new StopwatchTimer(mClock, null, -400, null,
-                mOnBatteryTimeBase, in);
-        mMobileRadioActivePerAppTimer = new StopwatchTimer(mClock, null, -401, null,
-                mOnBatteryTimeBase, in);
-        mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
-        mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
-        mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
-        mWifiMulticastWakelockTimer = new StopwatchTimer(mClock, null, -4, null,
-                mOnBatteryTimeBase, in);
-        mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
-        mWifiOn = false;
-        mWifiOnTimer = new StopwatchTimer(mClock, null, -4, null, mOnBatteryTimeBase, in);
-        mGlobalWifiRunning = false;
-        mGlobalWifiRunningTimer = new StopwatchTimer(mClock, null, -5, null,
-                mOnBatteryTimeBase, in);
-        for (int i=0; i<NUM_WIFI_STATES; i++) {
-            mWifiStateTimer[i] = new StopwatchTimer(mClock, null, -600 - i,
-                    null, mOnBatteryTimeBase, in);
-        }
-        for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
-            mWifiSupplStateTimer[i] = new StopwatchTimer(mClock, null, -700 - i,
-                    null, mOnBatteryTimeBase, in);
-        }
-        for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
-            mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClock, null, -800 - i,
-                    null, mOnBatteryTimeBase, in);
-        }
-        mWifiActiveTimer = new StopwatchTimer(mClock, null, -900, null,
-            mOnBatteryTimeBase, in);
-        mWifiActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase,
-                NUM_WIFI_TX_LEVELS, in);
-        for (int i=0; i<mGpsSignalQualityTimer.length; i++) {
-            mGpsSignalQualityTimer[i] = new StopwatchTimer(mClock, null, -1000 - i,
-                null, mOnBatteryTimeBase, in);
-        }
-        mBluetoothActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase,
-                NUM_BT_TX_LEVELS, in);
-        mModemActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase,
-                ModemActivityInfo.getNumTxPowerLevels(), in);
-        mHasWifiReporting = in.readInt() != 0;
-        mHasBluetoothReporting = in.readInt() != 0;
-        mHasModemReporting = in.readInt() != 0;
-
-        mNumConnectivityChange = in.readInt();
-        mAudioOnNesting = 0;
-        // TODO: It's likely a mistake that mAudioOnTimer/mVideoOnTimer don't write/read to parcel!
-        mAudioOnTimer = new StopwatchTimer(mClock, null, -7, null, mOnBatteryTimeBase);
-        mVideoOnNesting = 0;
-        mVideoOnTimer = new StopwatchTimer(mClock, null, -8, null, mOnBatteryTimeBase);
-        mFlashlightOnNesting = 0;
-        mFlashlightOnTimer = new StopwatchTimer(mClock, null, -9, null, mOnBatteryTimeBase, in);
-        mCameraOnNesting = 0;
-        mCameraOnTimer = new StopwatchTimer(mClock, null, -13, null, mOnBatteryTimeBase, in);
-        mBluetoothScanNesting = 0;
-        mBluetoothScanTimer = new StopwatchTimer(mClock, null, -14, null, mOnBatteryTimeBase, in);
-        mDischargeUnplugLevel = in.readInt();
-        mDischargePlugLevel = in.readInt();
-        mDischargeCurrentLevel = in.readInt();
-        mCurrentBatteryLevel = in.readInt();
-        mLowDischargeAmountSinceCharge = in.readInt();
-        mHighDischargeAmountSinceCharge = in.readInt();
-        mDischargeAmountScreenOn = in.readInt();
-        mDischargeAmountScreenOnSinceCharge = in.readInt();
-        mDischargeAmountScreenOff = in.readInt();
-        mDischargeAmountScreenOffSinceCharge = in.readInt();
-        mDischargeAmountScreenDoze = in.readInt();
-        mDischargeAmountScreenDozeSinceCharge = in.readInt();
-        mDischargeStepTracker.readFromParcel(in);
-        mChargeStepTracker.readFromParcel(in);
-        mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in);
-        mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase, in);
-        mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in);
-        mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in);
-        mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in);
-        mLastWriteTimeMs = in.readLong();
-        mBatteryTimeToFullSeconds = in.readLong();
-
-
-        final MeasuredEnergyStats.Config config = MeasuredEnergyStats.Config.createFromParcel(in);
-        final MeasuredEnergyStats measuredEnergyStats =
-                MeasuredEnergyStats.createFromParcel(mMeasuredEnergyStatsConfig, in);
-        if (config != null && Arrays.equals(config.getStateNames(),
-                getBatteryConsumerProcessStateNames())) {
-            mMeasuredEnergyStatsConfig = config;
-            mGlobalMeasuredEnergyStats = measuredEnergyStats;
-        }
-
-        mRpmStats.clear();
-        int NRPMS = in.readInt();
-        for (int irpm = 0; irpm < NRPMS; irpm++) {
-            if (in.readInt() != 0) {
-                String rpmName = in.readString();
-                SamplingTimer rpmt = new SamplingTimer(mClock, mOnBatteryTimeBase, in);
-                mRpmStats.put(rpmName, rpmt);
-            }
-        }
-        mScreenOffRpmStats.clear();
-        int NSORPMS = in.readInt();
-        for (int irpm = 0; irpm < NSORPMS; irpm++) {
-            if (in.readInt() != 0) {
-                String rpmName = in.readString();
-                SamplingTimer rpmt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase, in);
-                mScreenOffRpmStats.put(rpmName, rpmt);
-            }
-        }
-
-        mKernelWakelockStats.clear();
-        int NKW = in.readInt();
-        for (int ikw = 0; ikw < NKW; ikw++) {
-            if (in.readInt() != 0) {
-                String wakelockName = in.readString();
-                SamplingTimer kwlt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase, in);
-                mKernelWakelockStats.put(wakelockName, kwlt);
-            }
-        }
-
-        mWakeupReasonStats.clear();
-        int NWR = in.readInt();
-        for (int iwr = 0; iwr < NWR; iwr++) {
-            if (in.readInt() != 0) {
-                String reasonName = in.readString();
-                SamplingTimer timer = new SamplingTimer(mClock, mOnBatteryTimeBase, in);
-                mWakeupReasonStats.put(reasonName, timer);
-            }
-        }
-
-        mKernelMemoryStats.clear();
-        int nmt = in.readInt();
-        for (int imt = 0; imt < nmt; imt++) {
-            if (in.readInt() != 0) {
-                Long bucket = in.readLong();
-                SamplingTimer kmt = new SamplingTimer(mClock, mOnBatteryTimeBase, in);
-                mKernelMemoryStats.put(bucket, kmt);
-            }
-        }
-
-        mPartialTimers.clear();
-        mFullTimers.clear();
-        mWindowTimers.clear();
-        mWifiRunningTimers.clear();
-        mFullWifiLockTimers.clear();
-        mWifiScanTimers.clear();
-        mWifiBatchedScanTimers.clear();
-        mWifiMulticastTimers.clear();
-        mAudioTurnedOnTimers.clear();
-        mVideoTurnedOnTimers.clear();
-        mFlashlightTurnedOnTimers.clear();
-        mCameraTurnedOnTimers.clear();
-
-        int numUids = in.readInt();
-        mUidStats.clear();
-        final long elapsedRealtimeMs = mClock.elapsedRealtime();
-        final long uptimeMs = mClock.uptimeMillis();
-        for (int i = 0; i < numUids; i++) {
-            int uid = in.readInt();
-            Uid u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs);
-            u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase,
-                    in);
-            mUidStats.append(uid, u);
-        }
-
-        mBinderThreadCpuTimesUs = LongSamplingCounterArray.readFromParcel(in, mOnBatteryTimeBase);
-    }
-
-    @GuardedBy("this")
-    public void writeToParcel(Parcel out, int flags) {
-        writeToParcelLocked(out, true, flags);
-    }
-
-    @GuardedBy("this")
-    public void writeToParcelWithoutUids(Parcel out, int flags) {
-        writeToParcelLocked(out, false, flags);
-    }
-
-    @SuppressWarnings("unused")
-    @GuardedBy("this")
-    void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
-        // Need to update with current kernel wake lock counts.
-        pullPendingStateUpdatesLocked();
-
-        updateSystemServiceCallStats();
-
-        // Pull the clock time.  This may update the time and make a new history entry
-        // if we had originally pulled a time before the RTC was set.
-        getStartClockTime();
-
-        final long uSecUptime = mClock.uptimeMillis() * 1000;
-        final long uSecRealtime = mClock.elapsedRealtime() * 1000;
-        final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime);
-        final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime);
-
-        out.writeInt(MAGIC);
-
-        writeHistoryBuffer(out, true);
-        mBatteryStatsHistory.writeToParcel(out);
-
-        out.writeInt(mStartCount);
-        out.writeLong(mStartClockTimeMs);
-        out.writeString(mStartPlatformVersion);
-        out.writeString(mEndPlatformVersion);
-        out.writeLong(mUptimeUs);
-        out.writeLong(mUptimeStartUs);
-        out.writeLong(mRealtimeUs);
-        out.writeLong(mRealtimeStartUs);
-        out.writeInt(mOnBattery ? 1 : 0);
-        out.writeInt(mEstimatedBatteryCapacityMah);
-        out.writeInt(mLastLearnedBatteryCapacityUah);
-        out.writeInt(mMinLearnedBatteryCapacityUah);
-        out.writeInt(mMaxLearnedBatteryCapacityUah);
-        mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
-        mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
-
-        mScreenOnTimer.writeToParcel(out, uSecRealtime);
-        mScreenDozeTimer.writeToParcel(out, uSecRealtime);
-        for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) {
-            mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime);
-        }
-        mInteractiveTimer.writeToParcel(out, uSecRealtime);
-        mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime);
-        out.writeLong(mLongestLightIdleTimeMs);
-        out.writeLong(mLongestFullIdleTimeMs);
-        mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime);
-        mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime);
-        mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime);
-        mDeviceIdlingTimer.writeToParcel(out, uSecRealtime);
-        mPhoneOnTimer.writeToParcel(out, uSecRealtime);
-        for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) {
-            mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
-        }
-        mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime);
-        for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; i++) {
-            mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime);
-        }
-        for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
-            mNetworkByteActivityCounters[i].writeToParcel(out);
-            mNetworkPacketActivityCounters[i].writeToParcel(out);
-        }
-        mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime);
-        mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime);
-        mMobileRadioActiveAdjustedTime.writeToParcel(out);
-        mMobileRadioActiveUnknownTime.writeToParcel(out);
-        mMobileRadioActiveUnknownCount.writeToParcel(out);
-        mWifiMulticastWakelockTimer.writeToParcel(out, uSecRealtime);
-        mWifiOnTimer.writeToParcel(out, uSecRealtime);
-        mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime);
-        for (int i = 0; i < NUM_WIFI_STATES; i++) {
-            mWifiStateTimer[i].writeToParcel(out, uSecRealtime);
-        }
-        for (int i = 0; i < NUM_WIFI_SUPPL_STATES; i++) {
-            mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime);
-        }
-        for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
-            mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
-        }
-        mWifiActiveTimer.writeToParcel(out, uSecRealtime);
-        mWifiActivity.writeToParcel(out, 0);
-        for (int i = 0; i < mGpsSignalQualityTimer.length; i++) {
-            mGpsSignalQualityTimer[i].writeToParcel(out, uSecRealtime);
-        }
-        mBluetoothActivity.writeToParcel(out, 0);
-        mModemActivity.writeToParcel(out, 0);
-        out.writeInt(mHasWifiReporting ? 1 : 0);
-        out.writeInt(mHasBluetoothReporting ? 1 : 0);
-        out.writeInt(mHasModemReporting ? 1 : 0);
-
-        out.writeInt(mNumConnectivityChange);
-        mFlashlightOnTimer.writeToParcel(out, uSecRealtime);
-        mCameraOnTimer.writeToParcel(out, uSecRealtime);
-        mBluetoothScanTimer.writeToParcel(out, uSecRealtime);
-        out.writeInt(mDischargeUnplugLevel);
-        out.writeInt(mDischargePlugLevel);
-        out.writeInt(mDischargeCurrentLevel);
-        out.writeInt(mCurrentBatteryLevel);
-        out.writeInt(mLowDischargeAmountSinceCharge);
-        out.writeInt(mHighDischargeAmountSinceCharge);
-        out.writeInt(mDischargeAmountScreenOn);
-        out.writeInt(mDischargeAmountScreenOnSinceCharge);
-        out.writeInt(mDischargeAmountScreenOff);
-        out.writeInt(mDischargeAmountScreenOffSinceCharge);
-        out.writeInt(mDischargeAmountScreenDoze);
-        out.writeInt(mDischargeAmountScreenDozeSinceCharge);
-        mDischargeStepTracker.writeToParcel(out);
-        mChargeStepTracker.writeToParcel(out);
-        mDischargeCounter.writeToParcel(out);
-        mDischargeScreenOffCounter.writeToParcel(out);
-        mDischargeScreenDozeCounter.writeToParcel(out);
-        mDischargeLightDozeCounter.writeToParcel(out);
-        mDischargeDeepDozeCounter.writeToParcel(out);
-        out.writeLong(mLastWriteTimeMs);
-        out.writeLong(mBatteryTimeToFullSeconds);
-
-        MeasuredEnergyStats.Config.writeToParcel(mMeasuredEnergyStatsConfig, out);
-
-        if (mGlobalMeasuredEnergyStats != null) {
-            out.writeInt(1);
-            mGlobalMeasuredEnergyStats.writeToParcel(out);
-        } else {
-            out.writeInt(0);
-        }
-
-        out.writeInt(mRpmStats.size());
-        for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) {
-            SamplingTimer rpmt = ent.getValue();
-            if (rpmt != null) {
-                out.writeInt(1);
-                out.writeString(ent.getKey());
-                rpmt.writeToParcel(out, uSecRealtime);
-            } else {
-                out.writeInt(0);
-            }
-        }
-        out.writeInt(mScreenOffRpmStats.size());
-        for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) {
-            SamplingTimer rpmt = ent.getValue();
-            if (rpmt != null) {
-                out.writeInt(1);
-                out.writeString(ent.getKey());
-                rpmt.writeToParcel(out, uSecRealtime);
-            } else {
-                out.writeInt(0);
-            }
-        }
-
-        if (inclUids) {
-            out.writeInt(mKernelWakelockStats.size());
-            for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
-                SamplingTimer kwlt = ent.getValue();
-                if (kwlt != null) {
-                    out.writeInt(1);
-                    out.writeString(ent.getKey());
-                    kwlt.writeToParcel(out, uSecRealtime);
-                } else {
-                    out.writeInt(0);
-                }
-            }
-            out.writeInt(mWakeupReasonStats.size());
-            for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) {
-                SamplingTimer timer = ent.getValue();
-                if (timer != null) {
-                    out.writeInt(1);
-                    out.writeString(ent.getKey());
-                    timer.writeToParcel(out, uSecRealtime);
-                } else {
-                    out.writeInt(0);
-                }
-            }
-        } else {
-            out.writeInt(0);
-            out.writeInt(0);
-        }
-
-        out.writeInt(mKernelMemoryStats.size());
-        for (int i = 0; i < mKernelMemoryStats.size(); i++) {
-            SamplingTimer kmt = mKernelMemoryStats.valueAt(i);
-            if (kmt != null) {
-                out.writeInt(1);
-                out.writeLong(mKernelMemoryStats.keyAt(i));
-                kmt.writeToParcel(out, uSecRealtime);
-            } else {
-                out.writeInt(0);
-            }
-        }
-
-        if (inclUids) {
-            int size = mUidStats.size();
-            out.writeInt(size);
-            for (int i = 0; i < size; i++) {
-                out.writeInt(mUidStats.keyAt(i));
-                Uid uid = mUidStats.valueAt(i);
-
-                uid.writeToParcelLocked(out, uSecUptime, uSecRealtime);
-            }
-        } else {
-            out.writeInt(0);
-        }
-        LongSamplingCounterArray.writeToParcel(out, mBinderThreadCpuTimesUs);
-    }
-
-    private void writeCpuSpeedCountersToParcel(Parcel out, LongSamplingCounter[][] counters) {
-        if (counters == null) {
-            out.writeInt(0);
-            return;
-        }
-
-        out.writeInt(1);
-        out.writeInt(counters.length);
-        for (int i = 0; i < counters.length; i++) {
-            LongSamplingCounter[] counterArray = counters[i];
-            if (counterArray == null) {
-                out.writeInt(0);
-                continue;
-            }
-
-            out.writeInt(1);
-            out.writeInt(counterArray.length);
-            for (int j = 0; j < counterArray.length; j++) {
-                LongSamplingCounter c = counterArray[j];
-                if (c != null) {
-                    out.writeInt(1);
-                    c.writeToParcel(out);
-                } else {
-                    out.writeInt(0);
-                }
-            }
-        }
-    }
-
-    private LongSamplingCounter[][] readCpuSpeedCountersFromParcel(Parcel in) {
-        LongSamplingCounter[][] counters;
-        if (in.readInt() != 0) {
-            int numCpuClusters = in.readInt();
-            if (mPowerProfile != null
-                    && mPowerProfile.getNumCpuClusters() != numCpuClusters) {
-                throw new ParcelFormatException("Incompatible number of cpu clusters");
-            }
-
-            counters = new LongSamplingCounter[numCpuClusters][];
-            for (int cluster = 0; cluster < numCpuClusters; cluster++) {
-                if (in.readInt() != 0) {
-                    int numSpeeds = in.readInt();
-                    if (mPowerProfile != null
-                            && mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != numSpeeds) {
-                        throw new ParcelFormatException("Incompatible number of cpu speeds");
-                    }
-
-                    final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds];
-                    counters[cluster] = cpuSpeeds;
-                    for (int speed = 0; speed < numSpeeds; speed++) {
-                        if (in.readInt() != 0) {
-                            cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase, in);
-                        }
-                    }
-                } else {
-                    counters[cluster] = null;
-                }
-            }
-        } else {
-            counters = null;
-        }
-
-        return counters;
-    }
-
-    public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
-        new Parcelable.Creator<BatteryStatsImpl>() {
-        public BatteryStatsImpl createFromParcel(Parcel in) {
-            return new BatteryStatsImpl(in);
-        }
-
-        public BatteryStatsImpl[] newArray(int size) {
-            return new BatteryStatsImpl[size];
-        }
-    };
-
-    @GuardedBy("this")
     public void prepareForDumpLocked() {
         // Need to retrieve current kernel wake lock stats before printing.
         pullPendingStateUpdatesLocked();
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 71b1bc2..bec3754 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -1207,7 +1207,7 @@
         private int mImeBackDisposition = 0;
         private boolean mShowImeSwitcher = false;
         private IBinder mImeToken = null;
-        private LetterboxDetails[] mLetterboxDetails;
+        private LetterboxDetails[] mLetterboxDetails = new LetterboxDetails[0];
 
         private void setBarAttributes(@Appearance int appearance,
                 AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme,
diff --git a/services/core/java/com/android/server/timedetector/ConfigurationInternal.java b/services/core/java/com/android/server/timedetector/ConfigurationInternal.java
index 683eaeb..372bcc6 100644
--- a/services/core/java/com/android/server/timedetector/ConfigurationInternal.java
+++ b/services/core/java/com/android/server/timedetector/ConfigurationInternal.java
@@ -46,9 +46,10 @@
 
     private final boolean mAutoDetectionSupported;
     private final int mSystemClockUpdateThresholdMillis;
-    private final Instant mAutoTimeLowerBound;
+    private final Instant mAutoSuggestionLowerBound;
+    private final Instant mManualSuggestionLowerBound;
+    private final Instant mSuggestionUpperBound;
     private final @Origin int[] mOriginPriorities;
-    private final boolean mDeviceHasY2038Issue;
     private final boolean mAutoDetectionEnabledSetting;
     private final @UserIdInt int mUserId;
     private final boolean mUserConfigAllowed;
@@ -56,9 +57,10 @@
     private ConfigurationInternal(Builder builder) {
         mAutoDetectionSupported = builder.mAutoDetectionSupported;
         mSystemClockUpdateThresholdMillis = builder.mSystemClockUpdateThresholdMillis;
-        mAutoTimeLowerBound = Objects.requireNonNull(builder.mAutoTimeLowerBound);
+        mAutoSuggestionLowerBound = Objects.requireNonNull(builder.mAutoSuggestionLowerBound);
+        mManualSuggestionLowerBound = Objects.requireNonNull(builder.mManualSuggestionLowerBound);
+        mSuggestionUpperBound = Objects.requireNonNull(builder.mSuggestionUpperBound);
         mOriginPriorities = Objects.requireNonNull(builder.mOriginPriorities);
-        mDeviceHasY2038Issue = builder.mDeviceHasY2038Issue;
         mAutoDetectionEnabledSetting = builder.mAutoDetectionEnabledSetting;
 
         mUserId = builder.mUserId;
@@ -80,14 +82,31 @@
     }
 
     /**
-     * Returns the lower bound for valid automatic times. It is guaranteed to be in the past,
-     * i.e. it is unrelated to the current system clock time.
+     * Returns the lower bound for valid automatic time suggestions. It is guaranteed to be in the
+     * past, i.e. it is unrelated to the current system clock time.
      * It holds no other meaning; it could be related to when the device system image was built,
      * or could be updated by a mainline module.
      */
     @NonNull
-    public Instant getAutoTimeLowerBound() {
-        return mAutoTimeLowerBound;
+    public Instant getAutoSuggestionLowerBound() {
+        return mAutoSuggestionLowerBound;
+    }
+
+    /**
+     * Returns the lower bound for valid manual time suggestions. It is guaranteed to be in the
+     * past, i.e. it is unrelated to the current system clock time.
+     */
+    @NonNull
+    public Instant getManualSuggestionLowerBound() {
+        return mManualSuggestionLowerBound;
+    }
+
+    /**
+     * Returns the upper bound for valid time suggestions (manual and automatic).
+     */
+    @NonNull
+    public Instant getSuggestionUpperBound() {
+        return mSuggestionUpperBound;
     }
 
     /**
@@ -98,14 +117,6 @@
         return mOriginPriorities;
     }
 
-    /**
-     * Returns {@code true} if the device may be at risk of time_t overflow (because bionic
-     * defines time_t as a 32-bit signed integer for 32-bit processes).
-     */
-    public boolean getDeviceHasY2038Issue() {
-        return mDeviceHasY2038Issue;
-    }
-
     /** Returns the value of the auto time detection enabled setting. */
     public boolean getAutoDetectionEnabledSetting() {
         return mAutoDetectionEnabledSetting;
@@ -207,16 +218,17 @@
                 && mAutoDetectionEnabledSetting == that.mAutoDetectionEnabledSetting
                 && mUserId == that.mUserId && mUserConfigAllowed == that.mUserConfigAllowed
                 && mSystemClockUpdateThresholdMillis == that.mSystemClockUpdateThresholdMillis
-                && mAutoTimeLowerBound.equals(that.mAutoTimeLowerBound)
-                && mDeviceHasY2038Issue == that.mDeviceHasY2038Issue
+                && mAutoSuggestionLowerBound.equals(that.mAutoSuggestionLowerBound)
+                && mManualSuggestionLowerBound.equals(that.mManualSuggestionLowerBound)
+                && mSuggestionUpperBound.equals(that.mSuggestionUpperBound)
                 && Arrays.equals(mOriginPriorities, that.mOriginPriorities);
     }
 
     @Override
     public int hashCode() {
         int result = Objects.hash(mAutoDetectionSupported, mAutoDetectionEnabledSetting, mUserId,
-                mUserConfigAllowed, mSystemClockUpdateThresholdMillis, mAutoTimeLowerBound,
-                mDeviceHasY2038Issue);
+                mUserConfigAllowed, mSystemClockUpdateThresholdMillis, mAutoSuggestionLowerBound,
+                mManualSuggestionLowerBound, mSuggestionUpperBound);
         result = 31 * result + Arrays.hashCode(mOriginPriorities);
         return result;
     }
@@ -230,10 +242,13 @@
         return "ConfigurationInternal{"
                 + "mAutoDetectionSupported=" + mAutoDetectionSupported
                 + ", mSystemClockUpdateThresholdMillis=" + mSystemClockUpdateThresholdMillis
-                + ", mAutoTimeLowerBound=" + mAutoTimeLowerBound
-                + "(" + mAutoTimeLowerBound.toEpochMilli() + ")"
+                + ", mAutoSuggestionLowerBound=" + mAutoSuggestionLowerBound
+                + "(" + mAutoSuggestionLowerBound.toEpochMilli() + ")"
+                + ", mManualSuggestionLowerBound=" + mManualSuggestionLowerBound
+                + "(" + mManualSuggestionLowerBound.toEpochMilli() + ")"
+                + ", mSuggestionUpperBound=" + mSuggestionUpperBound
+                + "(" + mSuggestionUpperBound.toEpochMilli() + ")"
                 + ", mOriginPriorities=" + originPrioritiesString
-                + ", mDeviceHasY2038Issue=" + mDeviceHasY2038Issue
                 + ", mAutoDetectionEnabled=" + mAutoDetectionEnabledSetting
                 + ", mUserId=" + mUserId
                 + ", mUserConfigAllowed=" + mUserConfigAllowed
@@ -243,9 +258,10 @@
     static final class Builder {
         private boolean mAutoDetectionSupported;
         private int mSystemClockUpdateThresholdMillis;
-        @NonNull private Instant mAutoTimeLowerBound;
+        @NonNull private Instant mAutoSuggestionLowerBound;
+        @NonNull private Instant mManualSuggestionLowerBound;
+        @NonNull private Instant mSuggestionUpperBound;
         @NonNull private @Origin int[] mOriginPriorities;
-        private boolean mDeviceHasY2038Issue;
         private boolean mAutoDetectionEnabledSetting;
 
         private final @UserIdInt int mUserId;
@@ -263,9 +279,10 @@
             this.mUserConfigAllowed = toCopy.mUserConfigAllowed;
             this.mAutoDetectionSupported = toCopy.mAutoDetectionSupported;
             this.mSystemClockUpdateThresholdMillis = toCopy.mSystemClockUpdateThresholdMillis;
-            this.mAutoTimeLowerBound = toCopy.mAutoTimeLowerBound;
+            this.mAutoSuggestionLowerBound = toCopy.mAutoSuggestionLowerBound;
+            this.mManualSuggestionLowerBound = toCopy.mManualSuggestionLowerBound;
+            this.mSuggestionUpperBound = toCopy.mSuggestionUpperBound;
             this.mOriginPriorities = toCopy.mOriginPriorities;
-            this.mDeviceHasY2038Issue = toCopy.mDeviceHasY2038Issue;
             this.mAutoDetectionEnabledSetting = toCopy.mAutoDetectionEnabledSetting;
         }
 
@@ -296,10 +313,26 @@
         }
 
         /**
-         * Sets the lower bound for valid automatic times.
+         * Sets the lower bound for valid automatic time suggestions.
          */
-        public Builder setAutoTimeLowerBound(@NonNull Instant autoTimeLowerBound) {
-            mAutoTimeLowerBound = Objects.requireNonNull(autoTimeLowerBound);
+        public Builder setAutoSuggestionLowerBound(@NonNull Instant autoSuggestionLowerBound) {
+            mAutoSuggestionLowerBound = Objects.requireNonNull(autoSuggestionLowerBound);
+            return this;
+        }
+
+        /**
+         * Sets the lower bound for valid manual time suggestions.
+         */
+        public Builder setManualSuggestionLowerBound(@NonNull Instant manualSuggestionLowerBound) {
+            mManualSuggestionLowerBound = Objects.requireNonNull(manualSuggestionLowerBound);
+            return this;
+        }
+
+        /**
+         * Sets the upper bound for valid time suggestions (manual and automatic).
+         */
+        public Builder setSuggestionUpperBound(@NonNull Instant suggestionUpperBound) {
+            mSuggestionUpperBound = Objects.requireNonNull(suggestionUpperBound);
             return this;
         }
 
@@ -320,15 +353,6 @@
             return this;
         }
 
-        /**
-         * Returns {@code true} if the device may be at risk of time_t overflow (because bionic
-         * defines time_t as a 32-bit signed integer for 32-bit processes).
-         */
-        Builder setDeviceHasY2038Issue(boolean deviceHasY2038Issue) {
-            mDeviceHasY2038Issue = deviceHasY2038Issue;
-            return this;
-        }
-
         /** Returns a new {@link ConfigurationInternal}. */
         @NonNull
         ConfigurationInternal build() {
diff --git a/core/java/android/app/timedetector/GnssTimeSuggestion.java b/services/core/java/com/android/server/timedetector/GnssTimeSuggestion.java
similarity index 76%
rename from core/java/android/app/timedetector/GnssTimeSuggestion.java
rename to services/core/java/com/android/server/timedetector/GnssTimeSuggestion.java
index 3531b19..3349975 100644
--- a/core/java/android/app/timedetector/GnssTimeSuggestion.java
+++ b/services/core/java/com/android/server/timedetector/GnssTimeSuggestion.java
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 
-package android.app.timedetector;
+package com.android.server.timedetector;
 
 import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
+import android.app.timedetector.TimeSuggestionHelper;
 import android.os.ShellCommand;
 import android.os.TimestampedValue;
 
@@ -30,23 +29,8 @@
  * A time signal from a GNSS source.
  *
  * <p>See {@link TimeSuggestionHelper} for property information.
- *
- * @hide
  */
-public final class GnssTimeSuggestion implements Parcelable {
-
-    public static final @NonNull Creator<GnssTimeSuggestion> CREATOR =
-            new Creator<GnssTimeSuggestion>() {
-                public GnssTimeSuggestion createFromParcel(Parcel in) {
-                    TimeSuggestionHelper helper = TimeSuggestionHelper.handleCreateFromParcel(
-                            GnssTimeSuggestion.class, in);
-                    return new GnssTimeSuggestion(helper);
-                }
-
-                public GnssTimeSuggestion[] newArray(int size) {
-                    return new GnssTimeSuggestion[size];
-                }
-            };
+public final class GnssTimeSuggestion {
 
     @NonNull private final TimeSuggestionHelper mTimeSuggestionHelper;
 
@@ -58,16 +42,6 @@
         mTimeSuggestionHelper = Objects.requireNonNull(helper);
     }
 
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        mTimeSuggestionHelper.handleWriteToParcel(dest, flags);
-    }
-
     @NonNull
     public TimestampedValue<Long> getUnixEpochTime() {
         return mTimeSuggestionHelper.getUnixEpochTime();
diff --git a/services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java b/services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java
index 129810c..88e9fa5 100644
--- a/services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java
+++ b/services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java
@@ -19,8 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AlarmManager;
-import android.app.timedetector.GnssTimeSuggestion;
-import android.app.timedetector.TimeDetector;
 import android.content.Context;
 import android.location.Location;
 import android.location.LocationListener;
@@ -42,12 +40,13 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.time.Duration;
+import java.util.Objects;
 
 /**
  * Monitors the GNSS time.
  *
  * <p>When available, the time is always suggested to the {@link
- * com.android.server.timedetector.TimeDetectorService} where it may be used to set the device
+ * com.android.server.timedetector.TimeDetectorInternal} where it may be used to set the device
  * system clock, depending on user settings and what other signals are available.
  */
 public final class GnssTimeUpdateService extends Binder {
@@ -66,7 +65,16 @@
 
         @Override
         public void onStart() {
-            mService = new GnssTimeUpdateService(getContext());
+            Context context = getContext().createAttributionContext(ATTRIBUTION_TAG);
+            AlarmManager alarmManager = context.getSystemService(AlarmManager.class);
+            LocationManager locationManager = context.getSystemService(LocationManager.class);
+            LocationManagerInternal locationManagerInternal =
+                    LocalServices.getService(LocationManagerInternal.class);
+            TimeDetectorInternal timeDetectorInternal =
+                    LocalServices.getService(TimeDetectorInternal.class);
+
+            mService = new GnssTimeUpdateService(context, alarmManager, locationManager,
+                    locationManagerInternal, timeDetectorInternal);
             publishBinderService("gnss_time_update_service", mService);
         }
 
@@ -88,7 +96,7 @@
     private static final String ATTRIBUTION_TAG = "GnssTimeUpdateService";
 
     private final Context mContext;
-    private final TimeDetector mTimeDetector;
+    private final TimeDetectorInternal mTimeDetectorInternal;
     private final AlarmManager mAlarmManager;
     private final LocationManager mLocationManager;
     private final LocationManagerInternal mLocationManagerInternal;
@@ -98,12 +106,15 @@
     @Nullable private TimestampedValue<Long> mLastSuggestedGnssTime;
 
     @VisibleForTesting
-    GnssTimeUpdateService(@NonNull Context context) {
-        mContext = context.createAttributionContext(ATTRIBUTION_TAG);
-        mTimeDetector = mContext.getSystemService(TimeDetector.class);
-        mLocationManager = mContext.getSystemService(LocationManager.class);
-        mAlarmManager = mContext.getSystemService(AlarmManager.class);
-        mLocationManagerInternal = LocalServices.getService(LocationManagerInternal.class);
+    GnssTimeUpdateService(@NonNull Context context, @NonNull AlarmManager alarmManager,
+            @NonNull LocationManager locationManager,
+            @NonNull LocationManagerInternal locationManagerInternal,
+            @NonNull TimeDetectorInternal timeDetectorInternal) {
+        mContext = Objects.requireNonNull(context);
+        mAlarmManager = Objects.requireNonNull(alarmManager);
+        mLocationManager = Objects.requireNonNull(locationManager);
+        mLocationManagerInternal = Objects.requireNonNull(locationManagerInternal);
+        mTimeDetectorInternal = Objects.requireNonNull(timeDetectorInternal);
     }
 
     /**
@@ -191,7 +202,7 @@
         mLastSuggestedGnssTime = timeSignal;
 
         GnssTimeSuggestion timeSuggestion = new GnssTimeSuggestion(timeSignal);
-        mTimeDetector.suggestGnssTime(timeSuggestion);
+        mTimeDetectorInternal.suggestGnssTime(timeSuggestion);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/timedetector/NetworkTimeSuggestion.java b/services/core/java/com/android/server/timedetector/NetworkTimeSuggestion.java
new file mode 100644
index 0000000..f62c7ed
--- /dev/null
+++ b/services/core/java/com/android/server/timedetector/NetworkTimeSuggestion.java
@@ -0,0 +1,182 @@
+/*
+ * 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.server.timedetector;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.ShellCommand;
+import android.os.TimestampedValue;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A time signal from a network time source like NTP.
+ *
+ * <p>{@code unixEpochTime} is the suggested time. The {@code unixEpochTime.value} is the number of
+ * milliseconds elapsed since 1/1/1970 00:00:00 UTC according to the Unix time system. The {@code
+ * unixEpochTime.referenceTimeMillis} is the value of the elapsed realtime clock when the {@code
+ * unixEpochTime.value} was established. Note that the elapsed realtime clock is considered accurate
+ * but it is volatile, so time suggestions cannot be persisted across device resets.
+ *
+ * <p>{@code uncertaintyMillis} is an indication of error bounds associated the time. This is a
+ * positive value, and the correct Unix epoch time is <em>likely</em> to be within the bounds +/-
+ * the {@code uncertaintyMillis}. The Unix epoch time is not guaranteed to be within these bounds.
+ *
+ * <p>{@code debugInfo} contains debugging metadata associated with the suggestion. This is used to
+ * record why the suggestion exists and how it was entered. This information exists only to aid in
+ * debugging and therefore is used by {@link #toString()}, but it is not for use in detection
+ * logic and is not considered in {@link #hashCode()} or {@link #equals(Object)}.
+ */
+public final class NetworkTimeSuggestion {
+
+    @NonNull private final TimestampedValue<Long> mUnixEpochTime;
+    private final int mUncertaintyMillis;
+    @Nullable private ArrayList<String> mDebugInfo;
+
+    /**
+     * Create a {@link NetworkTimeSuggestion} with the supplied property values.
+     *
+     * <p>See {@link NetworkTimeSuggestion} for property details.
+     */
+    public NetworkTimeSuggestion(
+            @NonNull TimestampedValue<Long> unixEpochTime, int uncertaintyMillis) {
+        mUnixEpochTime = Objects.requireNonNull(unixEpochTime);
+        if (uncertaintyMillis < 0) {
+            throw new IllegalArgumentException("uncertaintyMillis < 0");
+        }
+        mUncertaintyMillis = uncertaintyMillis;
+    }
+
+    /** See {@link NetworkTimeSuggestion} for property details. */
+    @NonNull
+    public TimestampedValue<Long> getUnixEpochTime() {
+        return mUnixEpochTime;
+    }
+
+    /** See {@link NetworkTimeSuggestion} for property details. */
+    public int getUncertaintyMillis() {
+        return mUncertaintyMillis;
+    }
+
+    /** See {@link NetworkTimeSuggestion} for information about {@code debugInfo}. */
+    @NonNull
+    public List<String> getDebugInfo() {
+        return mDebugInfo == null
+                ? Collections.emptyList() : Collections.unmodifiableList(mDebugInfo);
+    }
+
+    /**
+     * Associates information with the instance that can be useful for debugging / logging. The
+     * information is present in {@link #toString()} but is not considered for {@link
+     * #equals(Object)} and {@link #hashCode()}.
+     */
+    public void addDebugInfo(String... debugInfos) {
+        if (mDebugInfo == null) {
+            mDebugInfo = new ArrayList<>();
+        }
+        mDebugInfo.addAll(Arrays.asList(debugInfos));
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof NetworkTimeSuggestion)) {
+            return false;
+        }
+        NetworkTimeSuggestion that = (NetworkTimeSuggestion) o;
+        return mUnixEpochTime.equals(that.mUnixEpochTime)
+                && mUncertaintyMillis == that.mUncertaintyMillis;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mUnixEpochTime, mUncertaintyMillis);
+    }
+
+    @Override
+    public String toString() {
+        return "NetworkTimeSuggestion{"
+                + "mUnixEpochTime=" + mUnixEpochTime
+                + ", mUncertaintyMillis=" + mUncertaintyMillis
+                + ", mDebugInfo=" + mDebugInfo
+                + '}';
+    }
+
+    /** Parses command line args to create a {@link NetworkTimeSuggestion}. */
+    public static NetworkTimeSuggestion parseCommandLineArg(@NonNull ShellCommand cmd)
+            throws IllegalArgumentException {
+        Long referenceTimeMillis = null;
+        Long unixEpochTimeMillis = null;
+        Integer uncertaintyMillis = null;
+        String opt;
+        while ((opt = cmd.getNextArg()) != null) {
+            switch (opt) {
+                case "--reference_time": {
+                    referenceTimeMillis = Long.parseLong(cmd.getNextArgRequired());
+                    break;
+                }
+                case "--unix_epoch_time": {
+                    unixEpochTimeMillis = Long.parseLong(cmd.getNextArgRequired());
+                    break;
+                }
+                case "--uncertainty_millis": {
+                    uncertaintyMillis = Integer.parseInt(cmd.getNextArgRequired());
+                    break;
+                }
+                default: {
+                    throw new IllegalArgumentException("Unknown option: " + opt);
+                }
+            }
+        }
+
+        if (referenceTimeMillis == null) {
+            throw new IllegalArgumentException("No referenceTimeMillis specified.");
+        }
+        if (unixEpochTimeMillis == null) {
+            throw new IllegalArgumentException("No unixEpochTimeMillis specified.");
+        }
+        if (uncertaintyMillis == null) {
+            throw new IllegalArgumentException("No uncertaintyMillis specified.");
+        }
+
+        TimestampedValue<Long> timeSignal =
+                new TimestampedValue<>(referenceTimeMillis, unixEpochTimeMillis);
+        NetworkTimeSuggestion networkTimeSuggestion =
+                new NetworkTimeSuggestion(timeSignal, uncertaintyMillis);
+        networkTimeSuggestion.addDebugInfo("Command line injection");
+        return networkTimeSuggestion;
+    }
+
+    /** Prints the command line args needed to create a {@link NetworkTimeSuggestion}. */
+    public static void printCommandLineOpts(PrintWriter pw) {
+        pw.printf("%s suggestion options:\n", "Network");
+        pw.println("  --reference_time <elapsed realtime millis> - the elapsed realtime millis when"
+                + " unix epoch time was read");
+        pw.println("  --unix_epoch_time <Unix epoch time millis>");
+        pw.println("  --uncertainty_millis <Uncertainty millis> - a positive error bound (+/-)"
+                + " estimate for unix epoch time");
+        pw.println();
+        pw.println("See " + NetworkTimeSuggestion.class.getName() + " for more information");
+    }
+}
diff --git a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
index 5389325..59c118d 100644
--- a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
+++ b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
@@ -20,8 +20,6 @@
 import android.annotation.Nullable;
 import android.app.AlarmManager;
 import android.app.PendingIntent;
-import android.app.timedetector.NetworkTimeSuggestion;
-import android.app.timedetector.TimeDetector;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -48,10 +46,12 @@
 import android.util.NtpTrustedTime.TimeResult;
 
 import com.android.internal.util.DumpUtils;
+import com.android.server.LocalServices;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.time.Duration;
+import java.util.Objects;
 
 /**
  * Monitors the network time. If looking up the network time fails for some reason, it tries a few
@@ -75,31 +75,20 @@
 
     private static final int POLL_REQUEST = 0;
 
-    private Network mDefaultNetwork = null;
-
     private final Context mContext;
     private final NtpTrustedTime mTime;
     private final AlarmManager mAlarmManager;
-    private final TimeDetector mTimeDetector;
+    private final TimeDetectorInternal mTimeDetectorInternal;
     private final ConnectivityManager mCM;
     private final PendingIntent mPendingPollIntent;
     private final PowerManager.WakeLock mWakeLock;
 
-    // NTP lookup is done on this thread and handler
-    private Handler mHandler;
-    private AutoTimeSettingObserver mAutoTimeSettingObserver;
-    private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback;
-
     // Normal polling frequency
     private final long mPollingIntervalMs;
     // Try-again polling interval, in case the network request failed
     private final long mPollingIntervalShorterMs;
     // Number of times to try again
     private final int mTryAgainTimesMax;
-    // Keeps track of how many quick attempts were made to fetch NTP time.
-    // During bootup, the network may not have been up yet, or it's taking time for the
-    // connection to happen.
-    private int mTryAgainCounter;
 
     /**
      * A log that records the decisions to fetch a network time update.
@@ -108,11 +97,29 @@
     @NonNull
     private final LocalLog mLocalLog = new LocalLog(30, false /* useLocalTimestamps */);
 
-    public NetworkTimeUpdateService(Context context) {
-        mContext = context;
+    // NTP lookup is done on this thread and handler
+    // @NonNull after systemRunning()
+    private Handler mHandler;
+    // @NonNull after systemRunning()
+    private AutoTimeSettingObserver mAutoTimeSettingObserver;
+    // @NonNull after systemRunning()
+    private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback;
+
+    // This field is only updated and accessed by the mHandler thread (except dump()).
+    @Nullable
+    private Network mDefaultNetwork = null;
+
+    // Keeps track of how many quick attempts were made to fetch NTP time.
+    // During bootup, the network may not have been up yet, or it's taking time for the
+    // connection to happen.
+    // This field is only updated and accessed by the mHandler thread (except dump()).
+    private int mTryAgainCounter;
+
+    public NetworkTimeUpdateService(@NonNull Context context) {
+        mContext = Objects.requireNonNull(context);
         mTime = NtpTrustedTime.getInstance(context);
         mAlarmManager = mContext.getSystemService(AlarmManager.class);
-        mTimeDetector = mContext.getSystemService(TimeDetector.class);
+        mTimeDetectorInternal = LocalServices.getService(TimeDetectorInternal.class);
         mCM = mContext.getSystemService(ConnectivityManager.class);
 
         Intent pollIntent = new Intent(ACTION_POLL, null);
@@ -196,36 +203,36 @@
      * Overrides the NTP server config for tests. Passing {@code null} to a parameter clears the
      * test value, i.e. so the normal value will be used next time.
      */
-    void setServerConfigForTests(
-            @Nullable String hostname, @Nullable Integer port, @Nullable Duration timeout) {
+    void setServerConfigForTests(@Nullable NtpTrustedTime.NtpConfig ntpConfig) {
         mContext.enforceCallingPermission(
                 android.Manifest.permission.SET_TIME, "set NTP server config for tests");
 
-        mLocalLog.log("Setting server config for tests: hostname=" + hostname
-                + ", port=" + port
-                + ", timeout=" + timeout);
-        mTime.setServerConfigForTests(hostname, port, timeout);
+        mLocalLog.log("Setting server config for tests: ntpConnectionInfo=" + ntpConfig);
+        mTime.setServerConfigForTests(ntpConfig);
     }
 
     private void onPollNetworkTime(int event) {
         // If we don't have any default network, don't bother.
-        if (mDefaultNetwork == null) return;
+        Network network = mDefaultNetwork;
+        if (network == null) return;
+
         mWakeLock.acquire();
         try {
-            onPollNetworkTimeUnderWakeLock(event);
+            onPollNetworkTimeUnderWakeLock(network, event);
         } finally {
             mWakeLock.release();
         }
     }
 
-    private void onPollNetworkTimeUnderWakeLock(int event) {
+    private void onPollNetworkTimeUnderWakeLock(@NonNull Network network, int event) {
         long currentElapsedRealtimeMillis = SystemClock.elapsedRealtime();
+
         // Force an NTP fix when outdated
         NtpTrustedTime.TimeResult cachedNtpResult = mTime.getCachedTimeResult();
         if (cachedNtpResult == null || cachedNtpResult.getAgeMillis(currentElapsedRealtimeMillis)
                 >= mPollingIntervalMs) {
-            if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh");
-            boolean isSuccessful = mTime.forceRefresh();
+            if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh using network=" + network);
+            boolean isSuccessful = mTime.forceRefresh(network);
             if (isSuccessful) {
                 mTryAgainCounter = 0;
             } else {
@@ -269,12 +276,15 @@
     }
 
     /** Suggests the time to the time detector. It may choose use it to set the system clock. */
-    private void makeNetworkTimeSuggestion(TimeResult ntpResult, String debugInfo) {
+    private void makeNetworkTimeSuggestion(
+            @NonNull TimeResult ntpResult, @NonNull String debugInfo) {
         TimestampedValue<Long> timeSignal = new TimestampedValue<>(
                 ntpResult.getElapsedRealtimeMillis(), ntpResult.getTimeMillis());
-        NetworkTimeSuggestion timeSuggestion = new NetworkTimeSuggestion(timeSignal);
+        NetworkTimeSuggestion timeSuggestion =
+                new NetworkTimeSuggestion(timeSignal, ntpResult.getUncertaintyMillis());
         timeSuggestion.addDebugInfo(debugInfo);
-        mTimeDetector.suggestNetworkTime(timeSuggestion);
+        timeSuggestion.addDebugInfo(ntpResult.toString());
+        mTimeDetectorInternal.suggestNetworkTime(timeSuggestion);
     }
 
     /**
@@ -297,7 +307,7 @@
         }
 
         @Override
-        public void handleMessage(Message msg) {
+        public void handleMessage(@NonNull Message msg) {
             switch (msg.what) {
                 case EVENT_AUTO_TIME_ENABLED:
                 case EVENT_POLL_NETWORK_TIME:
@@ -310,7 +320,7 @@
 
     private class NetworkTimeUpdateCallback extends NetworkCallback {
         @Override
-        public void onAvailable(Network network) {
+        public void onAvailable(@NonNull Network network) {
             Log.d(TAG, String.format("New default network %s; checking time.", network));
             mDefaultNetwork = network;
             // Running on mHandler so invoke directly.
@@ -318,7 +328,7 @@
         }
 
         @Override
-        public void onLost(Network network) {
+        public void onLost(@NonNull Network network) {
             if (network.equals(mDefaultNetwork)) mDefaultNetwork = null;
         }
     }
@@ -333,10 +343,10 @@
         private final int mMsg;
         private final Handler mHandler;
 
-        AutoTimeSettingObserver(Context context, Handler handler, int msg) {
+        AutoTimeSettingObserver(@NonNull Context context, @NonNull Handler handler, int msg) {
             super(handler);
-            mContext = context;
-            mHandler = handler;
+            mContext = Objects.requireNonNull(context);
+            mHandler = Objects.requireNonNull(handler);
             mMsg = msg;
         }
 
@@ -368,6 +378,7 @@
         pw.println("mPollingIntervalMs=" + Duration.ofMillis(mPollingIntervalMs));
         pw.println("mPollingIntervalShorterMs=" + Duration.ofMillis(mPollingIntervalShorterMs));
         pw.println("mTryAgainTimesMax=" + mTryAgainTimesMax);
+        pw.println("mDefaultNetwork=" + mDefaultNetwork);
         pw.println("mTryAgainCounter=" + mTryAgainCounter);
         pw.println();
         pw.println("NtpTrustedTime:");
diff --git a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateServiceShellCommand.java b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateServiceShellCommand.java
index 18dda55..410b50f 100644
--- a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateServiceShellCommand.java
+++ b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateServiceShellCommand.java
@@ -18,9 +18,14 @@
 
 import android.annotation.NonNull;
 import android.os.ShellCommand;
+import android.util.NtpTrustedTime;
 
 import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.time.Duration;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Objects;
 
 /** Implements the shell command interface for {@link NetworkTimeUpdateService}. */
@@ -42,13 +47,18 @@
     private static final String SHELL_COMMAND_FORCE_REFRESH = "force_refresh";
 
     /**
-     * A shell command that sets the NTP server config for tests. Config is cleared on reboot.
+     * A shell command that sets the NTP server config for tests. Config is cleared on reboot or
+     * using {@link #SHELL_COMMAND_RESET_SERVER_CONFIG}.
      */
-    private static final String SHELL_COMMAND_SET_SERVER_CONFIG = "set_server_config";
-    private static final String SET_SERVER_CONFIG_HOSTNAME_ARG = "--hostname";
-    private static final String SET_SERVER_CONFIG_PORT_ARG = "--port";
+    private static final String SHELL_COMMAND_SET_SERVER_CONFIG = "set_server_config_for_tests";
+    private static final String SET_SERVER_CONFIG_SERVER_ARG = "--server";
     private static final String SET_SERVER_CONFIG_TIMEOUT_ARG = "--timeout_millis";
 
+    /**
+     * A shell command that resets the NTP server config for tests.
+     */
+    private static final String SHELL_COMMAND_RESET_SERVER_CONFIG = "reset_server_config_for_tests";
+
     @NonNull
     private final NetworkTimeUpdateService mNetworkTimeUpdateService;
 
@@ -69,6 +79,8 @@
                 return runForceRefresh();
             case SHELL_COMMAND_SET_SERVER_CONFIG:
                 return runSetServerConfig();
+            case SHELL_COMMAND_RESET_SERVER_CONFIG:
+                return runResetServerConfig();
             default: {
                 return handleDefaultCommands(cmd);
             }
@@ -87,18 +99,17 @@
     }
 
     private int runSetServerConfig() {
-        String hostname = null;
-        Integer port = null;
+        List<URI> serverUris = new ArrayList<>();
         Duration timeout = null;
         String opt;
         while ((opt = getNextArg()) != null) {
             switch (opt) {
-                case SET_SERVER_CONFIG_HOSTNAME_ARG: {
-                    hostname = getNextArgRequired();
-                    break;
-                }
-                case SET_SERVER_CONFIG_PORT_ARG: {
-                    port = Integer.parseInt(getNextArgRequired());
+                case SET_SERVER_CONFIG_SERVER_ARG: {
+                    try {
+                        serverUris.add(NtpTrustedTime.parseNtpUriStrict(getNextArgRequired()));
+                    } catch (URISyntaxException e) {
+                        throw new IllegalArgumentException("Bad NTP server value", e);
+                    }
                     break;
                 }
                 case SET_SERVER_CONFIG_TIMEOUT_ARG: {
@@ -110,7 +121,23 @@
                 }
             }
         }
-        mNetworkTimeUpdateService.setServerConfigForTests(hostname, port, timeout);
+
+        if (serverUris.isEmpty()) {
+            throw new IllegalArgumentException(
+                    "Missing required option: --" + SET_SERVER_CONFIG_SERVER_ARG);
+        }
+        if (timeout == null) {
+            throw new IllegalArgumentException(
+                    "Missing required option: --" + SET_SERVER_CONFIG_TIMEOUT_ARG);
+        }
+
+        NtpTrustedTime.NtpConfig ntpConfig = new NtpTrustedTime.NtpConfig(serverUris, timeout);
+        mNetworkTimeUpdateService.setServerConfigForTests(ntpConfig);
+        return 0;
+    }
+
+    private int runResetServerConfig() {
+        mNetworkTimeUpdateService.setServerConfigForTests(null);
         return 0;
     }
 
@@ -126,11 +153,14 @@
         pw.printf("    Refreshes the latest time. Prints whether it was successful.\n");
         pw.printf("  %s\n", SHELL_COMMAND_SET_SERVER_CONFIG);
         pw.printf("    Sets the NTP server config for tests. The config is not persisted.\n");
-        pw.printf("      Options: [%s <hostname>] [%s <port>] [%s <millis>]\n",
-                SET_SERVER_CONFIG_HOSTNAME_ARG, SET_SERVER_CONFIG_PORT_ARG,
+        pw.printf("      Options: %s <uri> [%s <additional uris>]+ %s <millis>\n",
+                SET_SERVER_CONFIG_SERVER_ARG, SET_SERVER_CONFIG_SERVER_ARG,
                 SET_SERVER_CONFIG_TIMEOUT_ARG);
-        pw.printf("      Each key/value is optional and must be specified to override the\n");
-        pw.printf("      normal value, not specifying a key causes it to reset to the original.\n");
+        pw.printf("      NTP server URIs must be in the form \"ntp://hostname\" or"
+                + " \"ntp://hostname:port\"");
+        pw.printf("  %s\n", SHELL_COMMAND_RESET_SERVER_CONFIG);
+        pw.printf("    Resets/clears the NTP server config set via %s.\n",
+                SHELL_COMMAND_SET_SERVER_CONFIG);
         pw.println();
     }
 }
diff --git a/services/core/java/com/android/server/timedetector/ServiceConfigAccessorImpl.java b/services/core/java/com/android/server/timedetector/ServiceConfigAccessorImpl.java
index e4f3a80..888304a 100644
--- a/services/core/java/com/android/server/timedetector/ServiceConfigAccessorImpl.java
+++ b/services/core/java/com/android/server/timedetector/ServiceConfigAccessorImpl.java
@@ -31,6 +31,7 @@
 import android.app.time.TimeCapabilities;
 import android.app.time.TimeCapabilitiesAndConfig;
 import android.app.time.TimeConfiguration;
+import android.app.timedetector.TimeDetectorHelper;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -38,7 +39,6 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.database.ContentObserver;
-import android.os.Build;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -74,13 +74,6 @@
     private static final @Origin int[]
             DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES = { ORIGIN_TELEPHONY, ORIGIN_NETWORK };
 
-    /**
-     * Time in the past. If an automatic time suggestion is before this point, it is sure to be
-     * incorrect.
-     */
-    private static final Instant TIME_LOWER_BOUND_DEFAULT = Instant.ofEpochMilli(
-            Long.max(android.os.Environment.getRootDirectory().lastModified(), Build.TIME));
-
     /** Device config keys that affect the {@link TimeDetectorService}. */
     private static final Set<String> SERVER_FLAGS_KEYS_TO_WATCH = Set.of(
             KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE,
@@ -237,14 +230,16 @@
     @Override
     @NonNull
     public synchronized ConfigurationInternal getConfigurationInternal(@UserIdInt int userId) {
+        TimeDetectorHelper timeDetectorHelper = TimeDetectorHelper.INSTANCE;
         return new ConfigurationInternal.Builder(userId)
                 .setUserConfigAllowed(isUserConfigAllowed(userId))
                 .setAutoDetectionSupported(isAutoDetectionSupported())
                 .setAutoDetectionEnabledSetting(getAutoDetectionEnabledSetting())
                 .setSystemClockUpdateThresholdMillis(getSystemClockUpdateThresholdMillis())
-                .setAutoTimeLowerBound(getAutoTimeLowerBound())
+                .setAutoSuggestionLowerBound(getAutoSuggestionLowerBound())
+                .setManualSuggestionLowerBound(timeDetectorHelper.getManualSuggestionLowerBound())
+                .setSuggestionUpperBound(timeDetectorHelper.getSuggestionUpperBound())
                 .setOriginPriorities(getOriginPriorities())
-                .setDeviceHasY2038Issue(getDeviceHasY2038Issue())
                 .build();
     }
 
@@ -291,9 +286,9 @@
     }
 
     @NonNull
-    private Instant getAutoTimeLowerBound() {
+    private Instant getAutoSuggestionLowerBound() {
         return mServerFlags.getOptionalInstant(KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE)
-                .orElse(TIME_LOWER_BOUND_DEFAULT);
+                .orElse(TimeDetectorHelper.INSTANCE.getAutoSuggestionLowerBoundDefault());
     }
 
     @NonNull
@@ -310,10 +305,6 @@
         return DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES;
     }
 
-    private boolean getDeviceHasY2038Issue() {
-        return Build.SUPPORTED_32_BIT_ABIS.length > 0;
-    }
-
     /**
      * A base supplier of an array of time origin integers in priority order.
      * It handles memoization of the result to avoid repeated string parsing when nothing has
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorInternal.java b/services/core/java/com/android/server/timedetector/TimeDetectorInternal.java
new file mode 100644
index 0000000..eae12c2
--- /dev/null
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorInternal.java
@@ -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.server.timedetector;
+
+import android.annotation.NonNull;
+
+/**
+ * The internal (in-process) system server API for the {@link
+ * com.android.server.timedetector.TimeDetectorService}.
+ *
+ * <p>The methods on this class can be called from any thread.
+ * @hide
+ */
+public interface TimeDetectorInternal {
+
+    /** Used to pass new network time suggestions to the time detector. */
+    void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSignal);
+
+    /** Used to pass new GNSS time suggestions to the time detector. */
+    void suggestGnssTime(@NonNull GnssTimeSuggestion timeSignal);
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorInternalImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorInternalImpl.java
new file mode 100644
index 0000000..5a3e20e
--- /dev/null
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorInternalImpl.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.server.timedetector;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Handler;
+
+import java.util.Objects;
+
+/**
+ * The real {@link TimeDetectorInternal} local service implementation.
+ *
+ * @hide
+ */
+public class TimeDetectorInternalImpl implements TimeDetectorInternal {
+
+    @NonNull private final Context mContext;
+    @NonNull private final Handler mHandler;
+    @NonNull private final TimeDetectorStrategy mTimeDetectorStrategy;
+
+    public TimeDetectorInternalImpl(@NonNull Context context, @NonNull Handler handler,
+            @NonNull TimeDetectorStrategy timeDetectorStrategy) {
+        mContext = Objects.requireNonNull(context);
+        mHandler = Objects.requireNonNull(handler);
+        mTimeDetectorStrategy = Objects.requireNonNull(timeDetectorStrategy);
+    }
+
+    @Override
+    public void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSignal) {
+        Objects.requireNonNull(timeSignal);
+
+        mHandler.post(() -> mTimeDetectorStrategy.suggestNetworkTime(timeSignal));
+    }
+
+    @Override
+    public void suggestGnssTime(@NonNull GnssTimeSuggestion timeSignal) {
+        Objects.requireNonNull(timeSignal);
+
+        mHandler.post(() -> mTimeDetectorStrategy.suggestGnssTime(timeSignal));
+    }
+}
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
index 105cd78..5c47abf 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
@@ -24,20 +24,21 @@
 import android.app.time.ITimeDetectorListener;
 import android.app.time.TimeCapabilitiesAndConfig;
 import android.app.time.TimeConfiguration;
-import android.app.timedetector.GnssTimeSuggestion;
 import android.app.timedetector.ITimeDetectorService;
 import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timedetector.NetworkTimeSuggestion;
 import android.app.timedetector.TelephonyTimeSuggestion;
+import android.app.timedetector.TimePoint;
 import android.content.Context;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.ParcelableException;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ShellCallback;
 import android.util.ArrayMap;
 import android.util.IndentingPrintWriter;
+import android.util.NtpTrustedTime;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
@@ -49,6 +50,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.time.DateTimeException;
 import java.util.Objects;
 
 /**
@@ -79,6 +81,11 @@
             TimeDetectorStrategy timeDetectorStrategy =
                     TimeDetectorStrategyImpl.create(context, handler, serviceConfigAccessor);
 
+            // Create and publish the local service for use by internal callers.
+            TimeDetectorInternal internal =
+                    new TimeDetectorInternalImpl(context, handler, timeDetectorStrategy);
+            publishLocalService(TimeDetectorInternal.class, internal);
+
             TimeDetectorService service = new TimeDetectorService(
                     context, handler, serviceConfigAccessor, timeDetectorStrategy);
 
@@ -93,6 +100,7 @@
     @NonNull private final CallerIdentityInjector mCallerIdentityInjector;
     @NonNull private final ServiceConfigAccessor mServiceConfigAccessor;
     @NonNull private final TimeDetectorStrategy mTimeDetectorStrategy;
+    @NonNull private final NtpTrustedTime mNtpTrustedTime;
 
     /**
      * Holds the listeners. The key is the {@link IBinder} associated with the listener, the value
@@ -107,19 +115,21 @@
             @NonNull ServiceConfigAccessor serviceConfigAccessor,
             @NonNull TimeDetectorStrategy timeDetectorStrategy) {
         this(context, handler, serviceConfigAccessor, timeDetectorStrategy,
-                CallerIdentityInjector.REAL);
+                CallerIdentityInjector.REAL, NtpTrustedTime.getInstance(context));
     }
 
     @VisibleForTesting
     public TimeDetectorService(@NonNull Context context, @NonNull Handler handler,
             @NonNull ServiceConfigAccessor serviceConfigAccessor,
             @NonNull TimeDetectorStrategy timeDetectorStrategy,
-            @NonNull CallerIdentityInjector callerIdentityInjector) {
+            @NonNull CallerIdentityInjector callerIdentityInjector,
+            @NonNull NtpTrustedTime ntpTrustedTime) {
         mContext = Objects.requireNonNull(context);
         mHandler = Objects.requireNonNull(handler);
         mServiceConfigAccessor = Objects.requireNonNull(serviceConfigAccessor);
         mTimeDetectorStrategy = Objects.requireNonNull(timeDetectorStrategy);
         mCallerIdentityInjector = Objects.requireNonNull(callerIdentityInjector);
+        mNtpTrustedTime = Objects.requireNonNull(ntpTrustedTime);
 
         // Wire up a change listener so that ITimeZoneDetectorListeners can be notified when
         // the configuration changes for any reason.
@@ -283,16 +293,14 @@
         }
     }
 
-    @Override
-    public void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSignal) {
+    void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSignal) {
         enforceSuggestNetworkTimePermission();
         Objects.requireNonNull(timeSignal);
 
         mHandler.post(() -> mTimeDetectorStrategy.suggestNetworkTime(timeSignal));
     }
 
-    @Override
-    public void suggestGnssTime(@NonNull GnssTimeSuggestion timeSignal) {
+    void suggestGnssTime(@NonNull GnssTimeSuggestion timeSignal) {
         enforceSuggestGnssTimePermission();
         Objects.requireNonNull(timeSignal);
 
@@ -308,6 +316,19 @@
     }
 
     @Override
+    public TimePoint latestNetworkTime() {
+        // TODO(b/222295093): Return the latest network time from mTimeDetectorStrategy once we can
+        //  be sure that all uses of NtpTrustedTime results in a suggestion being made to the time
+        //  detector. mNtpTrustedTime can be removed once this happens.
+        NtpTrustedTime.TimeResult ntpResult = mNtpTrustedTime.getCachedTimeResult();
+        if (ntpResult != null) {
+            return new TimePoint(ntpResult.getTimeMillis(), ntpResult.getElapsedRealtimeMillis());
+        } else {
+            throw new ParcelableException(new DateTimeException("Missing network time fix"));
+        }
+    }
+
+    @Override
     protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw,
             @Nullable String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java b/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
index 211ebe4..d306d10 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
@@ -30,9 +30,7 @@
 
 import android.app.time.ExternalTimeSuggestion;
 import android.app.time.TimeConfiguration;
-import android.app.timedetector.GnssTimeSuggestion;
 import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timedetector.NetworkTimeSuggestion;
 import android.app.timedetector.TelephonyTimeSuggestion;
 import android.os.ShellCommand;
 import android.os.UserHandle;
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
index cec383c..141cdcf 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
@@ -20,9 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
 import android.app.time.ExternalTimeSuggestion;
-import android.app.timedetector.GnssTimeSuggestion;
 import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timedetector.NetworkTimeSuggestion;
 import android.app.timedetector.TelephonyTimeSuggestion;
 import android.os.TimestampedValue;
 import android.util.IndentingPrintWriter;
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
index ecbf1f8..547cf9d 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
@@ -25,9 +25,7 @@
 import android.annotation.UserIdInt;
 import android.app.AlarmManager;
 import android.app.time.ExternalTimeSuggestion;
-import android.app.timedetector.GnssTimeSuggestion;
 import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timedetector.NetworkTimeSuggestion;
 import android.app.timedetector.TelephonyTimeSuggestion;
 import android.content.Context;
 import android.os.Handler;
@@ -86,9 +84,6 @@
      */
     private static final int KEEP_SUGGESTION_HISTORY_SIZE = 10;
 
-    /** The value in Unix epoch milliseconds of the Y2038 issue. */
-    private static final long Y2038_LIMIT_IN_MILLIS = 1000L * Integer.MAX_VALUE;
-
     /**
      * A log that records the decisions / decision metadata that affected the device's system clock
      * time. This is logged in bug reports to assist with debugging issues with detection.
@@ -250,7 +245,7 @@
 
         final TimestampedValue<Long> newUnixEpochTime = suggestion.getUnixEpochTime();
 
-        if (!validateSuggestionTime(newUnixEpochTime, suggestion)) {
+        if (!validateManualSuggestionTime(newUnixEpochTime, suggestion)) {
             return false;
         }
 
@@ -426,7 +421,7 @@
     }
 
     @GuardedBy("this")
-    private boolean validateSuggestionTime(
+    private boolean validateSuggestionCommon(
             @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) {
         if (newUnixEpochTime.getValue() == null) {
             Slog.w(LOG_TAG, "Suggested time value is null. suggestion=" + suggestion);
@@ -443,8 +438,8 @@
             return false;
         }
 
-        if (newUnixEpochTime.getValue() > Y2038_LIMIT_IN_MILLIS
-                && mCurrentConfigurationInternal.getDeviceHasY2038Issue()) {
+        if (newUnixEpochTime.getValue()
+                > mCurrentConfigurationInternal.getSuggestionUpperBound().toEpochMilli()) {
             // This check won't prevent a device's system clock exceeding Integer.MAX_VALUE Unix
             // seconds through the normal passage of time, but it will stop it jumping above 2038
             // because of a "bad" suggestion. b/204193177
@@ -455,20 +450,40 @@
         return true;
     }
 
+    /**
+     * Returns {@code true} if an automatic time suggestion time is valid.
+     * See also {@link #validateManualSuggestionTime(TimestampedValue, Object)}.
+     */
     @GuardedBy("this")
     private boolean validateAutoSuggestionTime(
             @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion)  {
-        return validateSuggestionTime(newUnixEpochTime, suggestion)
-                && validateSuggestionAgainstLowerBound(newUnixEpochTime, suggestion);
+        Instant lowerBound = mCurrentConfigurationInternal.getAutoSuggestionLowerBound();
+        return validateSuggestionCommon(newUnixEpochTime, suggestion)
+                && validateSuggestionAgainstLowerBound(newUnixEpochTime, suggestion,
+                lowerBound);
+    }
+
+    /**
+     * Returns {@code true} if a manual time suggestion time is valid.
+     * See also {@link #validateAutoSuggestionTime(TimestampedValue, Object)}.
+     */
+    @GuardedBy("this")
+    private boolean validateManualSuggestionTime(
+            @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion)  {
+        Instant lowerBound = mCurrentConfigurationInternal.getManualSuggestionLowerBound();
+
+        // Suggestion is definitely wrong if it comes before lower time bound.
+        return validateSuggestionCommon(newUnixEpochTime, suggestion)
+                && validateSuggestionAgainstLowerBound(newUnixEpochTime, suggestion, lowerBound);
     }
 
     @GuardedBy("this")
     private boolean validateSuggestionAgainstLowerBound(
-            @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) {
-        Instant lowerBound = mCurrentConfigurationInternal.getAutoTimeLowerBound();
+            @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion,
+            @NonNull Instant lowerBound) {
 
         // Suggestion is definitely wrong if it comes before lower time bound.
-        if (lowerBound.isAfter(Instant.ofEpochMilli(newUnixEpochTime.getValue()))) {
+        if (lowerBound.toEpochMilli() > newUnixEpochTime.getValue()) {
             Slog.w(LOG_TAG, "Suggestion points to time before lower bound, skipping it. "
                     + "suggestion=" + suggestion + ", lower bound=" + lowerBound);
             return false;
diff --git a/services/core/java/com/android/server/timezonedetector/GeolocationTimeZoneSuggestion.java b/services/core/java/com/android/server/timezonedetector/GeolocationTimeZoneSuggestion.java
index f4a6ef0..8218fa5 100644
--- a/services/core/java/com/android/server/timezonedetector/GeolocationTimeZoneSuggestion.java
+++ b/services/core/java/com/android/server/timezonedetector/GeolocationTimeZoneSuggestion.java
@@ -189,6 +189,10 @@
             }
         }
 
+        if (zoneIdsString == null) {
+            throw new IllegalArgumentException("Missing --zone_ids");
+        }
+
         long elapsedRealtimeMillis = SystemClock.elapsedRealtime();
         List<String> zoneIds = parseZoneIdsArg(zoneIdsString);
         GeolocationTimeZoneSuggestion suggestion =
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/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 c2b6b19..6c1f3bb 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) {
@@ -9766,6 +9771,7 @@
 
     void setPictureInPictureParams(PictureInPictureParams p) {
         pictureInPictureArgs.copyOnlySet(p);
+        adjustPictureInPictureParamsIfNeeded(getBounds());
         getTask().getRootTask().onPictureInPictureParamsChanged();
     }
 
@@ -9812,6 +9818,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..3e62a29 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -56,6 +56,7 @@
 import static android.os.Process.INVALID_UID;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.TRANSIT_OPEN;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
@@ -201,8 +202,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 +612,6 @@
         mInTaskFragment = starter.mInTaskFragment;
         mAddingToTask = starter.mAddingToTask;
 
-        mNewTaskInfo = starter.mNewTaskInfo;
-        mNewTaskIntent = starter.mNewTaskIntent;
         mSourceRootTask = starter.mSourceRootTask;
 
         mTargetTask = starter.mTargetTask;
@@ -728,13 +725,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 +1217,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 +1643,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 +1667,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 +1811,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 +2409,6 @@
         mInTaskFragment = null;
         mAddingToTask = false;
 
-        mNewTaskInfo = null;
-        mNewTaskIntent = null;
         mSourceRootTask = null;
 
         mTargetRootTask = null;
@@ -2438,7 +2432,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 +2442,7 @@
         mOptions = options;
         mCallingUid = r.launchedFromUid;
         mSourceRecord = sourceRecord;
+        mSourceRootTask = mSourceRecord != null ? mSourceRecord.getRootTask() : null;
         mVoiceSession = voiceSession;
         mVoiceInteractor = voiceInteractor;
         mRestrictedBgActivity = restrictedBgActivity;
@@ -2502,10 +2497,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 +2561,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 +2603,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 +2691,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 +2884,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");
@@ -3024,6 +2973,7 @@
         if (taskFragment.isOrganized()) {
             mService.mWindowOrganizerController.sendTaskFragmentOperationFailure(
                     taskFragment.getTaskFragmentOrganizer(), mRequest.errorCallbackToken,
+                    taskFragment, HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT,
                     new SecurityException(errMsg));
         } else {
             // If the taskFragment is not organized, just dump error message as warning logs.
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..1898cc6 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;
@@ -204,8 +204,11 @@
         for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
             final WindowToken token = mTargetWindowTokens.keyAt(i);
             for (int j = token.getChildCount() - 1; j >= 0; j--) {
-                // TODO(b/234585256): The consumer should be handleFinishDrawing().
-                token.getChildAt(j).applyWithNextDraw(t -> {});
+                // TODO(b/234585256): The consumer should be handleFinishDrawing(). And check why
+                //  the local window might easily time out.
+                final WindowState w = token.getChildAt(j);
+                if (w.isClientLocal()) continue;
+                w.applyWithNextDraw(t -> {});
             }
         }
         mIsSyncDrawRequested = true;
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..b54cd41 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -67,6 +67,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
 import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
@@ -161,6 +162,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;
@@ -228,6 +230,7 @@
 import android.window.IDisplayAreaOrganizer;
 import android.window.TransitionRequestInfo;
 
+import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -268,6 +271,8 @@
     /** For {@link #setForcedScalingMode} to apply flag {@link Display#FLAG_SCALING_DISABLED}. */
     static final int FORCE_SCALING_MODE_DISABLED = 1;
 
+    static final float INVALID_DPI = 0.0f;
+
     @IntDef(prefix = { "FORCE_SCALING_MODE_" }, value = {
             FORCE_SCALING_MODE_AUTO,
             FORCE_SCALING_MODE_DISABLED
@@ -1074,7 +1079,7 @@
         mDisplayPolicy = new DisplayPolicy(mWmService, this);
         mDisplayRotation = new DisplayRotation(mWmService, this);
         mCloseToSquareMaxAspectRatio = mWmService.mContext.getResources().getFloat(
-                com.android.internal.R.dimen.config_closeToSquareDisplayMaxAspectRatio);
+                R.dimen.config_closeToSquareDisplayMaxAspectRatio);
         if (isDefaultDisplay) {
             // The policy may be invoked right after here, so it requires the necessary default
             // fields of this display content.
@@ -1363,7 +1368,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 +1377,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() {
@@ -1563,7 +1571,7 @@
                 mAtmService.mContext.createConfigurationContext(getConfiguration());
         final float minimalSize =
                 displayConfigurationContext.getResources().getDimension(
-                                com.android.internal.R.dimen.default_minimal_size_resizable_task);
+                        R.dimen.default_minimal_size_resizable_task);
         if (Double.compare(mDisplayMetrics.density, 0.0) == 0) {
             throw new IllegalArgumentException("Display with ID=" + getDisplayId() + "has invalid "
                 + "DisplayMetrics.density= 0.0");
@@ -1685,7 +1693,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
@@ -2931,7 +2939,15 @@
 
     /** If the given width and height equal to initial size, the setting will be cleared. */
     void setForcedSize(int width, int height) {
-        // Can't force size higher than the maximal allowed
+        setForcedSize(width, height, INVALID_DPI, INVALID_DPI);
+    }
+
+    /**
+     * If the given width and height equal to initial size, the setting will be cleared.
+     * If xPpi or yDpi is equal to {@link #INVALID_DPI}, the values are ignored.
+     */
+    void setForcedSize(int width, int height, float xDPI, float yDPI) {
+  	// Can't force size higher than the maximal allowed
         if (mMaxUiWidth > 0 && width > mMaxUiWidth) {
             final float ratio = mMaxUiWidth / (float) width;
             height = (int) (height * ratio);
@@ -2950,8 +2966,9 @@
         }
 
         Slog.i(TAG_WM, "Using new display size: " + width + "x" + height);
-        updateBaseDisplayMetrics(width, height, mBaseDisplayDensity, mBaseDisplayPhysicalXDpi,
-                mBaseDisplayPhysicalYDpi);
+        updateBaseDisplayMetrics(width, height, mBaseDisplayDensity,
+                xDPI != INVALID_DPI ? xDPI : mBaseDisplayPhysicalXDpi,
+                yDPI != INVALID_DPI ? yDPI : mBaseDisplayPhysicalYDpi);
         reconfigureDisplayLocked();
 
         if (!mIsSizeForced) {
@@ -3255,10 +3272,11 @@
     }
 
     public void setRotationAnimation(ScreenRotationAnimation screenRotationAnimation) {
-        if (mScreenRotationAnimation != null) {
-            mScreenRotationAnimation.kill();
-        }
+        final ScreenRotationAnimation prev = mScreenRotationAnimation;
         mScreenRotationAnimation = screenRotationAnimation;
+        if (prev != null) {
+            prev.kill();
+        }
 
         // Hide the windows which are not significant in rotation animation. So that the windows
         // don't need to block the unfreeze time.
@@ -3866,7 +3884,7 @@
             mAtmService.onImeWindowSetOnDisplayArea(imePid, mImeWindowsContainer);
         }
         mInsetsStateController.getSourceProvider(ITYPE_IME).setWindowContainer(win,
-                mDisplayPolicy.getImeSourceFrameProvider(), null /* imeFrameProvider */);
+                mDisplayPolicy.getImeSourceFrameProvider(), null);
         computeImeTarget(true /* updateImeTarget */);
         updateImeControlTarget();
     }
@@ -4247,6 +4265,17 @@
         void detach(Transaction t) {
             removeImeSurface(t);
         }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder(64);
+            sb.append("ImeScreenshot{");
+            sb.append(Integer.toHexString(System.identityHashCode(this)));
+            sb.append(" imeTarget=" + mImeTarget);
+            sb.append(" surface=" + mImeSurface);
+            sb.append('}');
+            return sb.toString();
+        }
     }
 
     private void attachAndShowImeScreenshotOnTarget() {
@@ -4279,15 +4308,23 @@
     }
 
     /**
-     * Removes the IME screenshot when necessary.
-     *
-     * Used when app transition animation finished or obsoleted screenshot surface like size
-     * changed by rotation.
+     * Removes the IME screenshot when the caller is a part of the attached target window.
      */
-    void removeImeScreenshotIfPossible() {
-        if (mImeLayeringTarget == null
-                || mImeLayeringTarget.mAttrs.type != TYPE_APPLICATION_STARTING
-                && !mImeLayeringTarget.inTransitionSelfOrParent()) {
+    void removeImeSurfaceByTarget(WindowContainer win) {
+        if (mImeScreenshot == null || win == null) {
+            return;
+        }
+        // The starting window shouldn't be the input target to attach the IME screenshot during
+        // transitioning.
+        if (win.asWindowState() != null
+                && win.asWindowState().mAttrs.type == TYPE_APPLICATION_STARTING) {
+            return;
+        }
+
+        final WindowState screenshotTarget = mImeScreenshot.getImeTarget();
+        final boolean winIsOrContainsScreenshotTarget = (win == screenshotTarget
+                || win.getWindow(w -> w == screenshotTarget) != null);
+        if (winIsOrContainsScreenshotTarget) {
             removeImeSurfaceImmediately();
         }
     }
@@ -4547,9 +4584,9 @@
         // if the wallpaper service is disabled on the device, we're never going to have
         // wallpaper, don't bother waiting for it
         boolean wallpaperEnabled = mWmService.mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_enableWallpaperService)
+                R.bool.config_enableWallpaperService)
                 && mWmService.mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_checkWallpaperAtBoot);
+                R.bool.config_checkWallpaperAtBoot);
 
         final boolean haveBootMsg = drawnWindowTypes.get(TYPE_BOOT_PROGRESS);
         final boolean haveApp = drawnWindowTypes.get(TYPE_BASE_APPLICATION);
@@ -4634,10 +4671,8 @@
                     wc, SurfaceAnimator.animationTypeToString(type), mImeScreenshot,
                     mImeScreenshot.getImeTarget());
         }
-        if (mImeScreenshot != null && (wc == mImeScreenshot.getImeTarget()
-                || wc.getWindow(w -> w == mImeScreenshot.getImeTarget()) != null)
-                && (type & WindowState.EXIT_ANIMATING_TYPES) != 0) {
-            removeImeSurfaceImmediately();
+        if ((type & WindowState.EXIT_ANIMATING_TYPES) != 0) {
+            removeImeSurfaceByTarget(wc);
         }
     }
 
@@ -4811,16 +4846,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
@@ -5565,11 +5592,13 @@
     private static boolean needsGestureExclusionRestrictions(WindowState win,
             boolean ignoreRequest) {
         final int type = win.mAttrs.type;
+        final int privateFlags = win.mAttrs.privateFlags;
         final boolean stickyHideNav =
                 !win.getRequestedVisibility(ITYPE_NAVIGATION_BAR)
                         && win.mAttrs.insetsFlags.behavior == BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
         return (!stickyHideNav || ignoreRequest) && type != TYPE_INPUT_METHOD
-                && type != TYPE_NOTIFICATION_SHADE && win.getActivityType() != ACTIVITY_TYPE_HOME;
+                && type != TYPE_NOTIFICATION_SHADE && win.getActivityType() != ACTIVITY_TYPE_HOME
+                && (privateFlags & PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION) == 0;
     }
 
     /**
@@ -5681,7 +5710,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);
 
@@ -6501,20 +6539,24 @@
     class RemoteInsetsControlTarget implements InsetsControlTarget {
         private final IDisplayWindowInsetsController mRemoteInsetsController;
         private final InsetsVisibilities mRequestedVisibilities = new InsetsVisibilities();
+        private final boolean mCanShowTransient;
 
         RemoteInsetsControlTarget(IDisplayWindowInsetsController controller) {
             mRemoteInsetsController = controller;
+            mCanShowTransient = mWmService.mContext.getResources().getBoolean(
+                    R.bool.config_remoteInsetsControllerSystemBarsCanBeShownByUserAction);
         }
 
         /**
          * 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);
             }
@@ -6559,6 +6601,11 @@
         }
 
         @Override
+        public boolean canShowTransient() {
+            return mCanShowTransient;
+        }
+
+        @Override
         public boolean getRequestedVisibility(@InternalInsetsType int type) {
             if (type == ITYPE_IME) {
                 return getInsetsStateController().getImeSourceProvider().isImeShowing();
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 95f7618..14e2241 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -46,9 +46,10 @@
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION;
 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;
@@ -219,6 +220,7 @@
     @Px
     private int mRightGestureInset;
 
+    private boolean mCanSystemBarsBeShownByUser;
     private boolean mNavButtonForcedVisible;
 
     StatusBarManagerInternal getStatusBarManagerInternal() {
@@ -424,6 +426,9 @@
         final Resources r = mContext.getResources();
         mCarDockEnablesAccelerometer = r.getBoolean(R.bool.config_carDockEnablesAccelerometer);
         mDeskDockEnablesAccelerometer = r.getBoolean(R.bool.config_deskDockEnablesAccelerometer);
+        mCanSystemBarsBeShownByUser = !r.getBoolean(
+                R.bool.config_remoteInsetsControllerControlsSystemBars) || r.getBoolean(
+                R.bool.config_remoteInsetsControllerSystemBarsCanBeShownByUserAction);
 
         mAccessibilityManager = (AccessibilityManager) mContext.getSystemService(
                 Context.ACCESSIBILITY_SERVICE);
@@ -616,7 +621,7 @@
         displayContent.mAppTransition.registerListenerLocked(mAppTransitionListener);
         displayContent.mTransitionController.registerLegacyListener(mAppTransitionListener);
         mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext, looper,
-                mService.mVrModeEnabled);
+                mService.mVrModeEnabled, mCanSystemBarsBeShownByUser);
 
         // TODO: Make it can take screenshot on external display
         mScreenshotHelper = displayContent.isDefaultDisplay
@@ -974,6 +979,10 @@
             }
         }
 
+        if (!win.mSession.mCanSetUnrestrictedGestureExclusion) {
+            attrs.privateFlags &= ~PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION;
+        }
+
         // Check if alternate bars positions were updated.
         if (mStatusBarAlt == win) {
             mStatusBarAltPosition = getAltBarPosition(attrs);
@@ -1156,7 +1165,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 =
@@ -1166,19 +1175,22 @@
                                         if (provider.type != ITYPE_NAVIGATION_BAR) {
                                             continue;
                                         }
-                                        calculateInsetsFrame(displayFrames, win, inOutFrame,
-                                                provider.source, provider.insetsSize,
-                                                lp.privateFlags, lp.gravity
-                                        );
+                                        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) -> {
@@ -1246,25 +1258,48 @@
                                             final LayoutParams lp =
                                                     win.mAttrs.forRotation(displayFrames.mRotation);
                                             final InsetsFrameProvider ifp =
-                                                    lp.providedInsets[index];
-                                            calculateInsetsFrame(displayFrames, windowContainer,
-                                                    inOutFrame, ifp.source, ifp.insetsSize,
-                                                    lp.privateFlags, lp.gravity);
+                                                    win.mAttrs.forRotation(displayFrames.mRotation)
+                                                            .providedInsets[index];
+                                            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 LayoutParams lp =
-                                                    win.mAttrs.forRotation(displayFrames.mRotation);
-                                            final InsetsFrameProvider ifp =
-                                                    lp.providedInsets[index];
-                                            calculateInsetsFrame(displayFrames, windowContainer,
-                                                    inOutFrame, ifp.source, ifp.imeInsetsSize,
-                                                    lp.privateFlags, lp.gravity);
-                                        } : 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);
                     }
                 }
@@ -1272,40 +1307,6 @@
         }
     }
 
-    private void calculateInsetsFrame(DisplayFrames df, WindowContainer container, Rect inOutFrame,
-            int source, Insets insetsSize, @LayoutParams.PrivateFlags int privateFlags,
-            int windowGravity) {
-        boolean extendByCutout = false;
-        if (source == InsetsFrameProvider.SOURCE_DISPLAY) {
-            inOutFrame.set(df.mUnrestricted);
-        } else if (source == InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS) {
-            inOutFrame.set(container.getBounds());
-        } 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(windowGravity, df.mDisplayCutoutSafe,
-                    df.mUnrestricted, inOutFrame, sTmpRect);
-        }
-    }
-
     @WindowManagerPolicy.AltBarPosition
     private int getAltBarPosition(WindowManager.LayoutParams params) {
         switch (params.gravity) {
@@ -2027,6 +2028,11 @@
         return lp.width;
     }
 
+    @VisibleForTesting
+    void setCanSystemBarsBeShownByUser(boolean canBeShown) {
+        mCanSystemBarsBeShownByUser = canBeShown;
+    }
+
     void notifyDisplayReady() {
         mHandler.post(() -> {
             final int displayId = getDisplayId();
@@ -2264,11 +2270,17 @@
         updateSystemBarAttributes();
     }
 
-    private void requestTransientBars(WindowState swipeTarget, boolean isGestureOnSystemBar) {
+    @VisibleForTesting
+    void requestTransientBars(WindowState swipeTarget, boolean isGestureOnSystemBar) {
         if (swipeTarget == null || !mService.mPolicy.isUserSetupComplete()) {
             // Swipe-up for navigation bar is disabled during setup
             return;
         }
+        if (!mCanSystemBarsBeShownByUser) {
+            Slog.d(TAG, "Remote insets controller disallows showing system bars - ignoring "
+                    + "request");
+            return;
+        }
         final InsetsSourceProvider provider = swipeTarget.getControllableInsetProvider();
         final InsetsControlTarget controlTarget = provider != null
                 ? provider.getControlTarget() : null;
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index b9d8319..3d91921 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -549,7 +549,7 @@
             // Go through all tasks and collect them before the rotation
             // TODO(shell-transitions): move collect() to onConfigurationChange once wallpaper
             //       handling is synchronized.
-            mDisplayContent.mTransitionController.collectForDisplayChange(mDisplayContent,
+            mDisplayContent.mTransitionController.collectForDisplayAreaChange(mDisplayContent,
                     null /* use collecting transition */);
         }
         mService.mAtmService.deferWindowLayout();
diff --git a/services/core/java/com/android/server/wm/DragDropController.java b/services/core/java/com/android/server/wm/DragDropController.java
index aa8ebf7..3108d4e 100644
--- a/services/core/java/com/android/server/wm/DragDropController.java
+++ b/services/core/java/com/android/server/wm/DragDropController.java
@@ -38,6 +38,8 @@
 import com.android.server.wm.WindowManagerInternal.IDragDropCallback;
 
 import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 
 /**
@@ -106,6 +108,8 @@
         final boolean callbackResult = mCallback.get().prePerformDrag(window, dragToken,
                 touchSource, touchX, touchY, thumbCenterX, thumbCenterY, data);
         try {
+            DisplayContent displayContent = null;
+            CompletableFuture<Boolean> touchFocusTransferredFuture = null;
             synchronized (mService.mGlobalLock) {
                 try {
                     if (!callbackResult) {
@@ -137,7 +141,7 @@
 
                     // !!! TODO(multi-display): support other displays
 
-                    final DisplayContent displayContent = callingWin.getDisplayContent();
+                    displayContent = callingWin.getDisplayContent();
                     if (displayContent == null) {
                         Slog.w(TAG_WM, "display content is null");
                         return null;
@@ -158,33 +162,9 @@
 
                     if ((flags & View.DRAG_FLAG_ACCESSIBILITY_ACTION) == 0) {
                         final Display display = displayContent.getDisplay();
-                        if (!mCallback.get().registerInputChannel(
+                        touchFocusTransferredFuture = mCallback.get().registerInputChannel(
                                 mDragState, display, mService.mInputManager,
-                                callingWin.mInputChannel)) {
-                            Slog.e(TAG_WM, "Unable to transfer touch focus");
-                            return null;
-                        }
-
-                        final SurfaceControl surfaceControl = mDragState.mSurfaceControl;
-                        mDragState.broadcastDragStartedLocked(touchX, touchY);
-                        mDragState.overridePointerIconLocked(touchSource);
-                        // remember the thumb offsets for later
-                        mDragState.mThumbOffsetX = thumbCenterX;
-                        mDragState.mThumbOffsetY = thumbCenterY;
-
-                        // Make the surface visible at the proper location
-                        if (SHOW_LIGHT_TRANSACTIONS) {
-                            Slog.i(TAG_WM, ">>> OPEN TRANSACTION performDrag");
-                        }
-
-                        final SurfaceControl.Transaction transaction = mDragState.mTransaction;
-                        transaction.setAlpha(surfaceControl, mDragState.mOriginalAlpha);
-                        transaction.show(surfaceControl);
-                        displayContent.reparentToOverlay(transaction, surfaceControl);
-                        mDragState.updateDragSurfaceLocked(true, touchX, touchY);
-                        if (SHOW_LIGHT_TRANSACTIONS) {
-                            Slog.i(TAG_WM, "<<< CLOSE TRANSACTION performDrag");
-                        }
+                                callingWin.mInputChannel);
                     } else {
                         // Skip surface logic for a drag triggered by an AccessibilityAction
                         mDragState.broadcastDragStartedLocked(touchX, touchY);
@@ -194,14 +174,51 @@
                                 getAccessibilityManager().getRecommendedTimeoutMillis(
                                         A11Y_DRAG_TIMEOUT_DEFAULT_MS,
                                         AccessibilityManager.FLAG_CONTENT_CONTROLS));
+
+                        return dragToken;
                     }
                 } finally {
                     if (surface != null) {
                         surface.release();
                     }
-                    if (mDragState != null && !mDragState.isInProgress()) {
-                        mDragState.closeLocked();
-                    }
+                }
+            }
+
+            boolean touchFocusTransferred = false;
+            try {
+                touchFocusTransferred = touchFocusTransferredFuture.get(DRAG_TIMEOUT_MS,
+                        TimeUnit.MILLISECONDS);
+            } catch (Exception exception) {
+                Slog.e(TAG_WM, "Exception thrown while waiting for touch focus transfer",
+                        exception);
+            }
+
+            synchronized (mService.mGlobalLock) {
+                if (!touchFocusTransferred) {
+                    Slog.e(TAG_WM, "Unable to transfer touch focus");
+                    mDragState.closeLocked();
+                    return null;
+                }
+
+                final SurfaceControl surfaceControl = mDragState.mSurfaceControl;
+                mDragState.broadcastDragStartedLocked(touchX, touchY);
+                mDragState.overridePointerIconLocked(touchSource);
+                // remember the thumb offsets for later
+                mDragState.mThumbOffsetX = thumbCenterX;
+                mDragState.mThumbOffsetY = thumbCenterY;
+
+                // Make the surface visible at the proper location
+                if (SHOW_LIGHT_TRANSACTIONS) {
+                    Slog.i(TAG_WM, ">>> OPEN TRANSACTION performDrag");
+                }
+
+                final SurfaceControl.Transaction transaction = mDragState.mTransaction;
+                transaction.setAlpha(surfaceControl, mDragState.mOriginalAlpha);
+                transaction.show(surfaceControl);
+                displayContent.reparentToOverlay(transaction, surfaceControl);
+                mDragState.updateDragSurfaceLocked(true, touchX, touchY);
+                if (SHOW_LIGHT_TRANSACTIONS) {
+                    Slog.i(TAG_WM, "<<< CLOSE TRANSACTION performDrag");
                 }
             }
             return dragToken;    // success!
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 475dd17..2242bfd 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -34,6 +34,8 @@
 import static com.android.server.wm.WindowManagerService.MY_PID;
 import static com.android.server.wm.WindowManagerService.MY_UID;
 
+import static java.util.concurrent.CompletableFuture.completedFuture;
+
 import android.animation.Animator;
 import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
@@ -70,6 +72,7 @@
 import com.android.server.pm.UserManagerInternal;
 
 import java.util.ArrayList;
+import java.util.concurrent.CompletableFuture;
 
 /**
  * Drag/drop state
@@ -160,7 +163,10 @@
         return mIsClosing;
     }
 
-    private void showInputSurface() {
+    /**
+     * @return a future that completes after window info is sent.
+     */
+    private CompletableFuture<Void> showInputSurface() {
         if (mInputSurface == null) {
             mInputSurface = mService.makeSurfaceBuilder(mDisplayContent.getSession())
                     .setContainerLayer()
@@ -173,7 +179,7 @@
         if (h == null) {
             Slog.w(TAG_WM, "Drag is in progress but there is no "
                     + "drag window handle.");
-            return;
+            return completedFuture(null);
         }
 
         // Crop the input surface to the display size.
@@ -184,10 +190,13 @@
                 .setLayer(mInputSurface, Integer.MAX_VALUE)
                 .setCrop(mInputSurface, mTmpClipRect);
 
-        // syncInputWindows here to ensure the input window info is sent before the
+        // A completableFuture is returned to ensure that input window info is sent before the
         // transferTouchFocus is called.
-        mTransaction.syncInputWindows()
-                .apply(true /*sync*/);
+        CompletableFuture<Void> result = new CompletableFuture<>();
+        mTransaction
+            .addWindowInfosReportedListener(() -> result.complete(null))
+            .apply();
+        return result;
     }
 
     /**
@@ -416,14 +425,15 @@
     /**
      * @param display The Display that the window being dragged is on.
      */
-    void register(Display display) {
+    CompletableFuture<Void> register(Display display) {
         display.getRealSize(mDisplaySize);
         if (DEBUG_DRAG) Slog.d(TAG_WM, "registering drag input channel");
         if (mInputInterceptor != null) {
             Slog.e(TAG_WM, "Duplicate register of drag input channel");
+            return completedFuture(null);
         } else {
             mInputInterceptor = new InputInterceptor(display);
-            showInputSurface();
+            return showInputSurface();
         }
     }
 
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/ImmersiveModeConfirmation.java b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
index 93bdf16..4c18d0b 100644
--- a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
+++ b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
@@ -99,9 +99,11 @@
     // Local copy of vr mode enabled state, to avoid calling into VrManager with
     // the lock held.
     private boolean mVrModeEnabled;
+    private boolean mCanSystemBarsBeShownByUser;
     private int mLockTaskState = LOCK_TASK_MODE_NONE;
 
-    ImmersiveModeConfirmation(Context context, Looper looper, boolean vrModeEnabled) {
+    ImmersiveModeConfirmation(Context context, Looper looper, boolean vrModeEnabled,
+            boolean canSystemBarsBeShownByUser) {
         final Display display = context.getDisplay();
         final Context uiContext = ActivityThread.currentActivityThread().getSystemUiContext();
         mContext = display.getDisplayId() == DEFAULT_DISPLAY
@@ -111,6 +113,7 @@
         mPanicThresholdMs = context.getResources()
                 .getInteger(R.integer.config_immersive_mode_confirmation_panic);
         mVrModeEnabled = vrModeEnabled;
+        mCanSystemBarsBeShownByUser = canSystemBarsBeShownByUser;
     }
 
     private long getNavBarExitDuration() {
@@ -171,6 +174,7 @@
             if ((DEBUG_SHOW_EVERY_TIME || !sConfirmed)
                     && userSetupComplete
                     && !mVrModeEnabled
+                    && mCanSystemBarsBeShownByUser
                     && !navBarEmpty
                     && !UserManager.isDeviceInDemoMode(mContext)
                     && (mLockTaskState != LOCK_TASK_MODE_LOCKED)) {
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..610ce35 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;
@@ -147,13 +150,13 @@
 
     void onDisplayRemoved() {
         mHandler.removeCallbacks(mUpdateInputWindows);
-        mHandler.post(() -> {
-            // Make sure any pending setInputWindowInfo transactions are completed. That prevents
-            // the timing of updating input info of removed display after cleanup.
-            mService.mTransactionFactory.get().syncInputWindows().apply();
-            // It calls InputDispatcher::setInputWindows directly.
-            mService.mInputManager.onDisplayRemoved(mDisplayId);
-        });
+        mService.mTransactionFactory.get()
+            // Make sure any pending setInputWindowInfo transactions are completed. That
+            // prevents the timing of updating input info of removed display after cleanup.
+            .addWindowInfosReportedListener(() ->
+                // It calls InputDispatcher::setInputWindows directly.
+                mService.mInputManager.onDisplayRemoved(mDisplayId))
+            .apply();
         mDisplayRemoved = true;
     }
 
@@ -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 ee1ff2c..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;
@@ -289,7 +290,7 @@
         // contains all insets types.
         final InsetsState originalState = mDisplayContent.getInsetsPolicy()
                 .enforceInsetsPolicyForTarget(type, WINDOWING_MODE_FULLSCREEN, alwaysOnTop,
-                        mStateController.getRawInsetsState());
+                        attrs.type, mStateController.getRawInsetsState());
         InsetsState state = adjustVisibilityForTransientTypes(originalState);
         return adjustInsetsForRoundedCorners(token, state, state == originalState);
     }
@@ -351,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) {
@@ -377,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);
             }
         }
 
@@ -548,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()) {
@@ -606,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/LaunchParamsUtil.java b/services/core/java/com/android/server/wm/LaunchParamsUtil.java
new file mode 100644
index 0000000..a618f7c
--- /dev/null
+++ b/services/core/java/com/android/server/wm/LaunchParamsUtil.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 com.android.server.wm;
+
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.util.DisplayMetrics.DENSITY_DEFAULT;
+
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.annotation.NonNull;
+import android.content.pm.ActivityInfo;
+import android.graphics.Rect;
+import android.util.Size;
+
+/**
+ * The static class that defines some utility constants and functions that are shared among launch
+ * params modifiers.
+ */
+class LaunchParamsUtil {
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "LaunchParamsUtil" : TAG_ATM;
+    private static final boolean DEBUG = false;
+
+    // Screen size of Nexus 5x
+    static final int DEFAULT_PORTRAIT_FREEFORM_WIDTH_DP = 412;
+    static final int DEFAULT_PORTRAIT_FREEFORM_HEIGHT_DP = 732;
+
+    // One of the most common tablet sizes that are small enough to fit in most large screens.
+    private static final int DEFAULT_LANDSCAPE_FREEFORM_WIDTH_DP = 1064;
+    private static final int DEFAULT_LANDSCAPE_FREEFORM_HEIGHT_DP = 600;
+
+    private LaunchParamsUtil() {}
+
+    /**
+     * Gets centered bounds of width x height. If inOutBounds is not empty, the result bounds
+     * centers at its center or displayArea's app bounds center if inOutBounds is empty.
+     */
+    static void centerBounds(@NonNull TaskDisplayArea displayArea, int width, int height,
+            @NonNull Rect inOutBounds) {
+        if (inOutBounds.isEmpty()) {
+            displayArea.getStableRect(inOutBounds);
+        }
+        final int left = inOutBounds.centerX() - width / 2;
+        final int top = inOutBounds.centerY() - height / 2;
+        inOutBounds.set(left, top, left + width, top + height);
+    }
+
+    /**
+     * Calculate the default size for a freeform environment. |defaultSize| is used as the default
+     * DP size, but if this is null, the portrait phone size is used.
+     */
+    static Size getDefaultFreeformSize(@NonNull ActivityInfo info,
+            @NonNull TaskDisplayArea displayArea,
+            @NonNull ActivityInfo.WindowLayout layout, int orientation,
+            @NonNull Rect stableBounds) {
+        // Get window size based on Nexus 5x screen, we assume that this is enough to show content
+        // of activities.
+        final float density = (float) displayArea.getConfiguration().densityDpi / DENSITY_DEFAULT;
+        final int freeformWidthInDp = (orientation == SCREEN_ORIENTATION_LANDSCAPE)
+                ? DEFAULT_LANDSCAPE_FREEFORM_WIDTH_DP : DEFAULT_PORTRAIT_FREEFORM_WIDTH_DP;
+        final int freeformHeightInDp = (orientation == SCREEN_ORIENTATION_LANDSCAPE)
+                ? DEFAULT_LANDSCAPE_FREEFORM_HEIGHT_DP : DEFAULT_PORTRAIT_FREEFORM_HEIGHT_DP;
+        final int freeformWidth = (int) (freeformWidthInDp * density + 0.5f);
+        final int freeformHeight = (int) (freeformHeightInDp * density + 0.5f);
+
+        // Minimum layout requirements.
+        final int layoutMinWidth = (layout == null) ? -1 : layout.minWidth;
+        final int layoutMinHeight = (layout == null) ? -1 : layout.minHeight;
+
+        // Max size, which is letterboxing/pillarboxing in displayArea. That's to say the large
+        // dimension of default size is the small dimension of displayArea size, and the small
+        // dimension of default size is calculated to keep the same aspect ratio as the
+        // displayArea's. Here we use stable bounds of displayArea because that indicates the area
+        // that isn't occupied by system widgets (e.g. sysbar and navbar).
+        final int portraitHeight = Math.min(stableBounds.width(), stableBounds.height());
+        final int otherDimension = Math.max(stableBounds.width(), stableBounds.height());
+        final int portraitWidth = (portraitHeight * portraitHeight) / otherDimension;
+        final int maxWidth = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? portraitHeight
+                : portraitWidth;
+        final int maxHeight = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? portraitWidth
+                : portraitHeight;
+        final int width = Math.min(maxWidth, Math.max(freeformWidth, layoutMinWidth));
+        final int height = Math.min(maxHeight, Math.max(freeformHeight, layoutMinHeight));
+        final float aspectRatio = (float) Math.max(width, height) / (float) Math.min(width, height);
+
+        // Aspect ratio requirements.
+        final float minAspectRatio = info.getMinAspectRatio(orientation);
+        final float maxAspectRatio = info.getMaxAspectRatio();
+
+        // Adjust the width and height to the aspect ratio requirements.
+        int adjWidth = width;
+        int adjHeight = height;
+        if (minAspectRatio >= 1 && aspectRatio < minAspectRatio) {
+            // The aspect ratio is below the minimum, adjust it to the minimum.
+            if (orientation == SCREEN_ORIENTATION_LANDSCAPE) {
+                // Fix the width, scale the height.
+                adjHeight = (int) (adjWidth / minAspectRatio + 0.5f);
+            } else {
+                // Fix the height, scale the width.
+                adjWidth = (int) (adjHeight / minAspectRatio + 0.5f);
+            }
+        } else if (maxAspectRatio >= 1 && aspectRatio > maxAspectRatio) {
+            // The aspect ratio exceeds the maximum, adjust it to the maximum.
+            if (orientation == SCREEN_ORIENTATION_LANDSCAPE) {
+                // Fix the width, scale the height.
+                adjHeight = (int) (adjWidth / maxAspectRatio + 0.5f);
+            } else {
+                // Fix the height, scale the width.
+                adjWidth = (int) (adjHeight / maxAspectRatio + 0.5f);
+            }
+        }
+
+        return new Size(adjWidth, adjHeight);
+    }
+}
diff --git a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
index d209f08..64749cf 100644
--- a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
+++ b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
@@ -101,7 +101,7 @@
 
         if (t != null) {
             mDisplayContent.mAtmService.startLaunchPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY);
-            mTransitionController.collectForDisplayChange(mDisplayContent, t);
+            mTransitionController.collectForDisplayAreaChange(mDisplayContent, t);
             mTransition = t;
         }
     }
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index f840171..ffe3374 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -520,7 +520,7 @@
     }
 
     private boolean matchesTarget(Task task) {
-        return task.mUserId == mUserId
+        return task.getNonFinishingActivityCount() > 0 && task.mUserId == mUserId
                 && task.getBaseIntent().getComponent().equals(mTargetIntent.getComponent());
     }
 }
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..fd8b614 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -40,9 +40,11 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.hardware.HardwareBuffer;
+import android.os.IBinder;
 import android.os.Trace;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
+import android.view.DisplayAddress;
 import android.view.DisplayInfo;
 import android.view.Surface;
 import android.view.Surface.OutOfResourcesException;
@@ -165,23 +167,43 @@
         final SurfaceControl.Transaction t = mService.mTransactionFactory.get();
 
         try {
-            SurfaceControl.LayerCaptureArgs.Builder builder =
-                    new SurfaceControl.LayerCaptureArgs.Builder(displayContent.getSurfaceControl())
-                            .setCaptureSecureLayers(true)
-                            .setAllowProtected(true)
-                            .setSourceCrop(new Rect(0, 0, width, height));
-
+            final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer;
             if (isSizeChanged) {
+                final DisplayAddress address = displayInfo.address;
+                if (!(address instanceof DisplayAddress.Physical)) {
+                    Slog.e(TAG, "Display does not have a physical address: " + displayId);
+                    return;
+                }
+                final DisplayAddress.Physical physicalAddress =
+                        (DisplayAddress.Physical) address;
+                final IBinder displayToken = SurfaceControl.getPhysicalDisplayToken(
+                        physicalAddress.getPhysicalDisplayId());
+                if (displayToken == null) {
+                    Slog.e(TAG, "Display token is null.");
+                    return;
+                }
+                // Temporarily not skip screenshot for the rounded corner overlays and screenshot
+                // the whole display to include the rounded corner overlays.
+                setSkipScreenshotForRoundedCornerOverlays(false, t);
                 mRoundedCornerOverlay = displayContent.findRoundedCornerOverlays();
+                final SurfaceControl.DisplayCaptureArgs captureArgs =
+                        new SurfaceControl.DisplayCaptureArgs.Builder(displayToken)
+                                .setSourceCrop(new Rect(0, 0, width, height))
+                                .setAllowProtected(true)
+                                .setCaptureSecureLayers(true)
+                                .build();
+                screenshotBuffer = SurfaceControl.captureDisplay(captureArgs);
             } 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.LayerCaptureArgs captureArgs =
+                        new SurfaceControl.LayerCaptureArgs.Builder(
+                                displayContent.getSurfaceControl())
+                                .setCaptureSecureLayers(true)
+                                .setAllowProtected(true)
+                                .setSourceCrop(new Rect(0, 0, width, height))
+                                .build();
+                screenshotBuffer = SurfaceControl.captureLayers(captureArgs);
             }
 
-            SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
-                    SurfaceControl.captureLayers(builder.build());
             if (screenshotBuffer == null) {
                 Slog.w(TAG, "Unable to take screenshot of display " + displayId);
                 return;
@@ -280,6 +302,21 @@
         t.apply();
     }
 
+    void setSkipScreenshotForRoundedCornerOverlays(
+            boolean skipScreenshot, SurfaceControl.Transaction t) {
+        mDisplayContent.forAllWindows(w -> {
+            if (!w.mToken.mRoundedCornerOverlay || !w.isVisible() || !w.mWinAnimator.hasSurface()) {
+                return;
+            }
+            t.setSkipScreenshot(w.mWinAnimator.mSurfaceController.mSurfaceControl, skipScreenshot);
+        }, false);
+        if (!skipScreenshot) {
+            // Use sync apply to apply the change immediately, so that the next
+            // SC.captureDisplay can capture the screen decor layers.
+            t.apply(true /* sync */);
+        }
+    }
+
     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
         proto.write(STARTED, mStarted);
@@ -488,10 +525,15 @@
                 }
                 mBackColorSurface = null;
             }
+
             if (mRoundedCornerOverlay != null) {
-                for (SurfaceControl sc : mRoundedCornerOverlay) {
-                    if (sc.isValid()) {
-                        t.show(sc);
+                if (mDisplayContent.getRotationAnimation() == null
+                        || mDisplayContent.getRotationAnimation() == this) {
+                    setSkipScreenshotForRoundedCornerOverlays(true, t);
+                    for (SurfaceControl sc : mRoundedCornerOverlay) {
+                        if (sc.isValid()) {
+                            t.show(sc);
+                        }
                     }
                 }
                 mRoundedCornerOverlay = null;
@@ -600,7 +642,7 @@
         }
 
         private SurfaceAnimator startDisplayRotation() {
-            return startAnimation(initializeBuilder()
+            SurfaceAnimator animator = startAnimation(initializeBuilder()
                             .setAnimationLeashParent(mDisplayContent.getSurfaceControl())
                             .setSurfaceControl(mDisplayContent.getWindowingLayer())
                             .setParentSurfaceControl(mDisplayContent.getSurfaceControl())
@@ -609,6 +651,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/Session.java b/services/core/java/com/android/server/wm/Session.java
index 9b013da..3577545 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -19,6 +19,7 @@
 import static android.Manifest.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 import static android.Manifest.permission.HIDE_OVERLAY_WINDOWS;
 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
+import static android.Manifest.permission.SET_UNRESTRICTED_GESTURE_EXCLUSION;
 import static android.Manifest.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS;
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
 import static android.Manifest.permission.SYSTEM_APPLICATION_OVERLAY;
@@ -109,6 +110,7 @@
 
     final boolean mCanCreateSystemApplicationOverlay;
     final boolean mCanHideNonSystemOverlayWindows;
+    final boolean mCanSetUnrestrictedGestureExclusion;
     private AlertWindowNotification mAlertWindowNotification;
     private boolean mShowingAlertWindowNotificationAllowed;
     private boolean mClientDead = false;
@@ -139,6 +141,9 @@
         mSetsUnrestrictedKeepClearAreas =
                 service.mContext.checkCallingOrSelfPermission(SET_UNRESTRICTED_KEEP_CLEAR_AREAS)
                         == PERMISSION_GRANTED;
+        mCanSetUnrestrictedGestureExclusion =
+                service.mContext.checkCallingOrSelfPermission(SET_UNRESTRICTED_GESTURE_EXCLUSION)
+                        == PERMISSION_GRANTED;
         mShowingAlertWindowNotificationAllowed = mService.mShowAlertWindowNotifications;
         mDragDropController = mService.mDragDropController;
         StringBuilder sb = new StringBuilder();
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index 392d4c2..d4551be 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -16,7 +16,7 @@
 
 package com.android.server.wm;
 
-import static android.window.TaskFragmentOrganizer.putExceptionInBundle;
+import static android.window.TaskFragmentOrganizer.putErrorInfoInBundle;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
 import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED;
@@ -214,12 +214,15 @@
             }
         }
 
-        void onTaskFragmentError(IBinder errorCallbackToken, Throwable exception) {
+        void onTaskFragmentError(IBinder errorCallbackToken, @Nullable TaskFragment taskFragment,
+                int opType, Throwable exception) {
             ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
                     "Sending TaskFragment error exception=%s", exception.toString());
-            final Bundle exceptionBundle = putExceptionInBundle(exception);
+            final TaskFragmentInfo info =
+                    taskFragment != null ? taskFragment.getTaskFragmentInfo() : null;
+            final Bundle errorBundle = putErrorInfoInBundle(exception, info, opType);
             try {
-                mOrganizer.onTaskFragmentError(errorCallbackToken, exceptionBundle);
+                mOrganizer.onTaskFragmentError(errorCallbackToken, errorBundle);
             } catch (RemoteException e) {
                 Slog.d(TAG, "Exception sending onTaskFragmentError callback", e);
             }
@@ -462,13 +465,15 @@
     }
 
     void onTaskFragmentError(ITaskFragmentOrganizer organizer, IBinder errorCallbackToken,
-            Throwable exception) {
+            TaskFragment taskFragment, int opType, Throwable exception) {
         validateAndGetState(organizer);
         Slog.w(TAG, "onTaskFragmentError ", exception);
         final PendingTaskFragmentEvent pendingEvent = new PendingTaskFragmentEvent.Builder(
                 PendingTaskFragmentEvent.EVENT_ERROR, organizer)
                 .setErrorCallbackToken(errorCallbackToken)
+                .setTaskFragment(taskFragment)
                 .setException(exception)
+                .setOpType(opType)
                 .build();
         mPendingTaskFragmentEvents.add(pendingEvent);
         // Make sure the error event will be dispatched if there are no other changes.
@@ -567,19 +572,22 @@
         // Set when the event is deferred due to the host task is invisible. The defer time will
         // be the last active time of the host task.
         private long mDeferTime;
+        private int mOpType;
 
         private PendingTaskFragmentEvent(@EventType int eventType,
                 ITaskFragmentOrganizer taskFragmentOrg,
                 @Nullable TaskFragment taskFragment,
                 @Nullable IBinder errorCallbackToken,
                 @Nullable Throwable exception,
-                @Nullable ActivityRecord activity) {
+                @Nullable ActivityRecord activity,
+                int opType) {
             mEventType = eventType;
             mTaskFragmentOrg = taskFragmentOrg;
             mTaskFragment = taskFragment;
             mErrorCallbackToken = errorCallbackToken;
             mException = exception;
             mActivity = activity;
+            mOpType = opType;
         }
 
         /**
@@ -610,6 +618,7 @@
             private Throwable mException;
             @Nullable
             private ActivityRecord mActivity;
+            private int mOpType;
 
             Builder(@EventType int eventType, ITaskFragmentOrganizer taskFragmentOrg) {
                 mEventType = eventType;
@@ -636,9 +645,14 @@
                 return this;
             }
 
+            Builder setOpType(int opType) {
+                mOpType = opType;
+                return this;
+            }
+
             PendingTaskFragmentEvent build() {
                 return new PendingTaskFragmentEvent(mEventType, mTaskFragmentOrg, mTaskFragment,
-                        mErrorCallbackToken, mException, mActivity);
+                        mErrorCallbackToken, mException, mActivity, mOpType);
             }
         }
     }
@@ -667,6 +681,10 @@
     }
 
     private boolean shouldSendEventWhenTaskInvisible(@NonNull PendingTaskFragmentEvent event) {
+        if (event.mEventType == PendingTaskFragmentEvent.EVENT_ERROR) {
+            return true;
+        }
+
         final TaskFragmentOrganizerState state =
                 mTaskFragmentOrganizerState.get(event.mTaskFragmentOrg.asBinder());
         final TaskFragmentInfo lastInfo = state.mLastSentTaskFragmentInfos.get(event.mTaskFragment);
@@ -757,7 +775,8 @@
                 state.onTaskFragmentParentInfoChanged(taskFragment);
                 break;
             case PendingTaskFragmentEvent.EVENT_ERROR:
-                state.onTaskFragmentError(event.mErrorCallbackToken, event.mException);
+                state.onTaskFragmentError(event.mErrorCallbackToken, taskFragment, event.mOpType,
+                        event.mException);
                 break;
             case PendingTaskFragmentEvent.EVENT_ACTIVITY_REPARENT_TO_TASK:
                 state.onActivityReparentToTask(event.mActivity);
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index 4141156..7b0337d 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -48,6 +48,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
+import android.util.Size;
 import android.util.Slog;
 import android.view.Gravity;
 import android.view.View;
@@ -67,10 +68,6 @@
     private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskLaunchParamsModifier" : TAG_ATM;
     private static final boolean DEBUG = false;
 
-    // Screen size of Nexus 5x
-    private static final int DEFAULT_PORTRAIT_PHONE_WIDTH_DP = 412;
-    private static final int DEFAULT_PORTRAIT_PHONE_HEIGHT_DP = 732;
-
     // Allowance of size matching.
     private static final int EPSILON = 2;
 
@@ -748,7 +745,10 @@
         }
 
         // First we get the default size we want.
-        getDefaultFreeformSize(root.info, displayArea, layout, orientation, mTmpBounds);
+        displayArea.getStableRect(mTmpStableBounds);
+        final Size defaultSize = LaunchParamsUtil.getDefaultFreeformSize(root.info, displayArea,
+                layout, orientation, mTmpStableBounds);
+        mTmpBounds.set(0, 0, defaultSize.getWidth(), defaultSize.getHeight());
         if (hasInitialBounds || sizeMatches(inOutBounds, mTmpBounds)) {
             // We're here because either input parameters specified initial bounds, or the suggested
             // bounds have the same size of the default freeform size. We should use the suggested
@@ -758,8 +758,8 @@
                 if (DEBUG) appendLog("freeform-size-orientation-match=" + inOutBounds);
             } else {
                 // Meh, orientation doesn't match. Let's rotate inOutBounds in-place.
-                centerBounds(displayArea, inOutBounds.height(), inOutBounds.width(),
-                        inOutBounds);
+                LaunchParamsUtil.centerBounds(displayArea, inOutBounds.height(),
+                        inOutBounds.width(), inOutBounds);
                 if (DEBUG) appendLog("freeform-orientation-mismatch=" + inOutBounds);
             }
         } else {
@@ -768,7 +768,7 @@
             // to the center of suggested bounds (or the displayArea if no suggested bounds). The
             // default size might be too big to center to source activity bounds in displayArea, so
             // we may need to move it back to the displayArea.
-            centerBounds(displayArea, mTmpBounds.width(), mTmpBounds.height(),
+            LaunchParamsUtil.centerBounds(displayArea, mTmpBounds.width(), mTmpBounds.height(),
                     inOutBounds);
             adjustBoundsToFitInDisplayArea(displayArea, inOutBounds);
             if (DEBUG) appendLog("freeform-size-mismatch=" + inOutBounds);
@@ -816,87 +816,6 @@
         return orientation;
     }
 
-    private void getDefaultFreeformSize(@NonNull ActivityInfo info,
-            @NonNull TaskDisplayArea displayArea,
-            @NonNull ActivityInfo.WindowLayout layout, int orientation, @NonNull Rect bounds) {
-        // Default size, which is letterboxing/pillarboxing in displayArea. That's to say the large
-        // dimension of default size is the small dimension of displayArea size, and the small
-        // dimension of default size is calculated to keep the same aspect ratio as the
-        // displayArea's. Here we use stable bounds of displayArea because that indicates the area
-        // that isn't occupied by system widgets (e.g. sysbar and navbar).
-        final Rect stableBounds = mTmpStableBounds;
-        displayArea.getStableRect(stableBounds);
-        final int portraitHeight = Math.min(stableBounds.width(), stableBounds.height());
-        final int otherDimension = Math.max(stableBounds.width(), stableBounds.height());
-        final int portraitWidth = (portraitHeight * portraitHeight) / otherDimension;
-        final int defaultWidth = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? portraitHeight
-                : portraitWidth;
-        final int defaultHeight = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? portraitWidth
-                : portraitHeight;
-
-        // Get window size based on Nexus 5x screen, we assume that this is enough to show content
-        // of activities.
-        final float density = (float) displayArea.getConfiguration().densityDpi / DENSITY_DEFAULT;
-        final int phonePortraitWidth = (int) (DEFAULT_PORTRAIT_PHONE_WIDTH_DP * density + 0.5f);
-        final int phonePortraitHeight = (int) (DEFAULT_PORTRAIT_PHONE_HEIGHT_DP * density + 0.5f);
-        final int phoneWidth = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? phonePortraitHeight
-                : phonePortraitWidth;
-        final int phoneHeight = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? phonePortraitWidth
-                : phonePortraitHeight;
-
-        // Minimum layout requirements.
-        final int layoutMinWidth = (layout == null) ? -1 : layout.minWidth;
-        final int layoutMinHeight = (layout == null) ? -1 : layout.minHeight;
-
-        // Aspect ratio requirements.
-        final float minAspectRatio = info.getMinAspectRatio(orientation);
-        final float maxAspectRatio = info.getMaxAspectRatio();
-
-        final int width = Math.min(defaultWidth, Math.max(phoneWidth, layoutMinWidth));
-        final int height = Math.min(defaultHeight, Math.max(phoneHeight, layoutMinHeight));
-        final float aspectRatio = (float) Math.max(width, height) / (float) Math.min(width, height);
-
-        // Adjust the width and height to the aspect ratio requirements.
-        int adjWidth = width;
-        int adjHeight = height;
-        if (minAspectRatio >= 1 && aspectRatio < minAspectRatio) {
-            // The aspect ratio is below the minimum, adjust it to the minimum.
-            if (orientation == SCREEN_ORIENTATION_LANDSCAPE) {
-                // Fix the width, scale the height.
-                adjHeight = (int) (adjWidth / minAspectRatio + 0.5f);
-            } else {
-                // Fix the height, scale the width.
-                adjWidth = (int) (adjHeight / minAspectRatio + 0.5f);
-            }
-        } else if (maxAspectRatio >= 1 && aspectRatio > maxAspectRatio) {
-            // The aspect ratio exceeds the maximum, adjust it to the maximum.
-            if (orientation == SCREEN_ORIENTATION_LANDSCAPE) {
-                // Fix the width, scale the height.
-                adjHeight = (int) (adjWidth / maxAspectRatio + 0.5f);
-            } else {
-                // Fix the height, scale the width.
-                adjWidth = (int) (adjHeight / maxAspectRatio + 0.5f);
-            }
-        }
-
-        bounds.set(0, 0, adjWidth, adjHeight);
-        bounds.offset(stableBounds.left, stableBounds.top);
-    }
-
-    /**
-     * Gets centered bounds of width x height. If inOutBounds is not empty, the result bounds
-     * centers at its center or displayArea's app bounds center if inOutBounds is empty.
-     */
-    private void centerBounds(@NonNull TaskDisplayArea displayArea, int width, int height,
-            @NonNull Rect inOutBounds) {
-        if (inOutBounds.isEmpty()) {
-            displayArea.getStableRect(inOutBounds);
-        }
-        final int left = inOutBounds.centerX() - width / 2;
-        final int top = inOutBounds.centerY() - height / 2;
-        inOutBounds.set(left, top, left + width, top + height);
-    }
-
     private void adjustBoundsToFitInDisplayArea(@NonNull TaskDisplayArea displayArea,
             @NonNull Rect inOutBounds) {
         final Rect stableBounds = mTmpStableBounds;
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/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 03ca4fd..5b32149 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -35,6 +35,8 @@
 import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP;
 import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP;
 
+import static java.util.concurrent.CompletableFuture.completedFuture;
+
 import android.annotation.NonNull;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -60,6 +62,8 @@
 import com.android.internal.policy.TaskResizingAlgorithm.CtrlType;
 import com.android.internal.protolog.common.ProtoLog;
 
+import java.util.concurrent.CompletableFuture;
+
 class TaskPositioner implements IBinder.DeathRecipient {
     private static final boolean DEBUG_ORIENTATION_VIOLATIONS = false;
     private static final String TAG_LOCAL = "TaskPositioner";
@@ -195,14 +199,14 @@
      * @param displayContent The Display that the window being dragged is on.
      * @param win The window which will be dragged.
      */
-    void register(DisplayContent displayContent, @NonNull WindowState win) {
+    CompletableFuture<Void> register(DisplayContent displayContent, @NonNull WindowState win) {
         if (DEBUG_TASK_POSITIONING) {
             Slog.d(TAG, "Registering task positioner");
         }
 
         if (mClientChannel != null) {
             Slog.e(TAG, "Task positioner already registered");
-            return;
+            return completedFuture(null);
         }
 
         mDisplayContent = displayContent;
@@ -235,27 +239,33 @@
         mDisplayContent.getDisplayRotation().pause();
 
         // Notify InputMonitor to take mDragWindowHandle.
-        mService.mTaskPositioningController.showInputSurface(win.getDisplayId());
+        return mService.mTaskPositioningController.showInputSurface(win.getDisplayId())
+            .thenRun(() -> {
+                // The global lock is held by the callers of register but released before the async
+                // results are waited on. We must acquire the lock in this callback to ensure thread
+                // safety.
+                synchronized (mService.mGlobalLock) {
+                    final Rect displayBounds = mTmpRect;
+                    displayContent.getBounds(displayBounds);
+                    final DisplayMetrics displayMetrics = displayContent.getDisplayMetrics();
+                    mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics);
+                    mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, displayMetrics);
+                    mMaxVisibleSize.set(displayBounds.width(), displayBounds.height());
 
-        final Rect displayBounds = mTmpRect;
-        displayContent.getBounds(displayBounds);
-        final DisplayMetrics displayMetrics = displayContent.getDisplayMetrics();
-        mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics);
-        mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, displayMetrics);
-        mMaxVisibleSize.set(displayBounds.width(), displayBounds.height());
+                    mDragEnded = false;
 
-        mDragEnded = false;
-
-        try {
-            mClientCallback = win.mClient.asBinder();
-            mClientCallback.linkToDeath(this, 0 /* flags */);
-        } catch (RemoteException e) {
-            // The caller has died, so clean up TaskPositioningController.
-            mService.mTaskPositioningController.finishTaskPositioning();
-            return;
-        }
-        mWindow = win;
-        mTask = win.getTask();
+                    try {
+                        mClientCallback = win.mClient.asBinder();
+                        mClientCallback.linkToDeath(this, 0 /* flags */);
+                    } catch (RemoteException e) {
+                        // The caller has died, so clean up TaskPositioningController.
+                        mService.mTaskPositioningController.finishTaskPositioning();
+                        return;
+                    }
+                    mWindow = win;
+                    mTask = win.getTask();
+                }
+            });
     }
 
     void unregister() {
diff --git a/services/core/java/com/android/server/wm/TaskPositioningController.java b/services/core/java/com/android/server/wm/TaskPositioningController.java
index 6dcad2b..55a3dec 100644
--- a/services/core/java/com/android/server/wm/TaskPositioningController.java
+++ b/services/core/java/com/android/server/wm/TaskPositioningController.java
@@ -19,6 +19,8 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
+import static java.util.concurrent.CompletableFuture.completedFuture;
+
 import android.annotation.Nullable;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -28,6 +30,8 @@
 import android.view.InputWindowHandle;
 import android.view.SurfaceControl;
 
+import java.util.concurrent.CompletableFuture;
+
 /**
  * Controller for task positioning by drag.
  */
@@ -58,14 +62,16 @@
     void hideInputSurface(int displayId) {
         if (mPositioningDisplay != null && mPositioningDisplay.getDisplayId() == displayId
                 && mInputSurface != null) {
-            mTransaction.hide(mInputSurface);
-            mTransaction.syncInputWindows().apply();
+            mTransaction.hide(mInputSurface).apply();
         }
     }
 
-    void showInputSurface(int displayId) {
+    /**
+     * @return a future that completes after window info is sent.
+     */
+    CompletableFuture<Void> showInputSurface(int displayId) {
         if (mPositioningDisplay == null || mPositioningDisplay.getDisplayId() != displayId) {
-            return;
+            return completedFuture(null);
         }
         final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
         if (mInputSurface == null) {
@@ -81,7 +87,7 @@
         if (h == null) {
             Slog.w(TAG_WM, "Drag is in progress but there is no "
                     + "drag window handle.");
-            return;
+            return completedFuture(null);
         }
 
         final Display display = dc.getDisplay();
@@ -89,25 +95,38 @@
         display.getRealSize(p);
         mTmpClipRect.set(0, 0, p.x, p.y);
 
+        CompletableFuture<Void> result = new CompletableFuture<>();
         mTransaction.show(mInputSurface)
                 .setInputWindowInfo(mInputSurface, h)
                 .setLayer(mInputSurface, Integer.MAX_VALUE)
                 .setPosition(mInputSurface, 0, 0)
                 .setCrop(mInputSurface, mTmpClipRect)
-                .syncInputWindows()
+                .addWindowInfosReportedListener(() -> result.complete(null))
                 .apply();
+        return result;
     }
 
     boolean startMovingTask(IWindow window, float startX, float startY) {
         WindowState win = null;
+        CompletableFuture<Boolean> startPositioningLockedFuture;
         synchronized (mService.mGlobalLock) {
             win = mService.windowForClientLocked(null, window, false);
-            // win shouldn't be null here, pass it down to startPositioningLocked
-            // to get warning if it's null.
-            if (!startPositioningLocked(
-                    win, false /*resize*/, false /*preserveOrientation*/, startX, startY)) {
+            startPositioningLockedFuture =
+                startPositioningLocked(
+                    win, false /*resize*/, false /*preserveOrientation*/, startX, startY);
+        }
+
+        try {
+            if (!startPositioningLockedFuture.get()) {
                 return false;
             }
+        } catch (Exception exception) {
+            Slog.e(TAG_WM, "Exception thrown while waiting for startPositionLocked future",
+                    exception);
+            return false;
+        }
+
+        synchronized (mService.mGlobalLock) {
             mService.mAtmService.setFocusedTask(win.getTask().mTaskId);
         }
         return true;
@@ -115,25 +134,37 @@
 
     void handleTapOutsideTask(DisplayContent displayContent, int x, int y) {
         mService.mH.post(() -> {
+            Task task;
+            CompletableFuture<Boolean> startPositioningLockedFuture;
             synchronized (mService.mGlobalLock) {
-                final Task task = displayContent.findTaskForResizePoint(x, y);
-                if (task != null) {
-                    if (!task.isResizeable()) {
-                        // The task is not resizable, so don't do anything when the user drags the
-                        // the resize handles.
-                        return;
-                    }
-                    if (!startPositioningLocked(task.getTopVisibleAppMainWindow(), true /*resize*/,
-                            task.preserveOrientationOnResize(), x, y)) {
-                        return;
-                    }
-                    mService.mAtmService.setFocusedTask(task.mTaskId);
+                task = displayContent.findTaskForResizePoint(x, y);
+                if (task == null || !task.isResizeable()) {
+                    // The task is not resizable, so don't do anything when the user drags the
+                    // the resize handles.
+                    return;
                 }
+                startPositioningLockedFuture =
+                    startPositioningLocked(task.getTopVisibleAppMainWindow(), true /*resize*/,
+                            task.preserveOrientationOnResize(), x, y);
+            }
+
+            try {
+                if (!startPositioningLockedFuture.get()) {
+                    return;
+                }
+            } catch (Exception exception) {
+                Slog.e(TAG_WM, "Exception thrown while waiting for startPositionLocked future",
+                        exception);
+                return;
+            }
+
+            synchronized (mService.mGlobalLock) {
+                mService.mAtmService.setFocusedTask(task.mTaskId);
             }
         });
     }
 
-    private boolean startPositioningLocked(WindowState win, boolean resize,
+    private CompletableFuture<Boolean> startPositioningLocked(WindowState win, boolean resize,
             boolean preserveOrientation, float startX, float startY) {
         if (DEBUG_TASK_POSITIONING)
             Slog.d(TAG_WM, "startPositioningLocked: "
@@ -142,43 +173,48 @@
 
         if (win == null || win.mActivityRecord == null) {
             Slog.w(TAG_WM, "startPositioningLocked: Bad window " + win);
-            return false;
+            return completedFuture(false);
         }
         if (win.mInputChannel == null) {
             Slog.wtf(TAG_WM, "startPositioningLocked: " + win + " has no input channel, "
                     + " probably being removed");
-            return false;
+            return completedFuture(false);
         }
 
         final DisplayContent displayContent = win.getDisplayContent();
         if (displayContent == null) {
             Slog.w(TAG_WM, "startPositioningLocked: Invalid display content " + win);
-            return false;
+            return completedFuture(false);
         }
         mPositioningDisplay = displayContent;
 
         mTaskPositioner = TaskPositioner.create(mService);
-        mTaskPositioner.register(displayContent, win);
+        return mTaskPositioner.register(displayContent, win).thenApply(unused -> {
+            // The global lock is held by the callers of startPositioningLocked but released before
+            // the async results are waited on. We must acquire the lock in this callback to ensure
+            // thread safety.
+            synchronized (mService.mGlobalLock) {
+                // We need to grab the touch focus so that the touch events during the
+                // resizing/scrolling are not sent to the app. 'win' is the main window
+                // of the app, it may not have focus since there might be other windows
+                // on top (eg. a dialog window).
+                WindowState transferFocusFromWin = win;
+                if (displayContent.mCurrentFocus != null && displayContent.mCurrentFocus != win
+                        && displayContent.mCurrentFocus.mActivityRecord == win.mActivityRecord) {
+                    transferFocusFromWin = displayContent.mCurrentFocus;
+                }
+                if (!mService.mInputManager.transferTouchFocus(
+                        transferFocusFromWin.mInputChannel, mTaskPositioner.mClientChannel,
+                        false /* isDragDrop */)) {
+                    Slog.e(TAG_WM, "startPositioningLocked: Unable to transfer touch focus");
+                    cleanUpTaskPositioner();
+                    return false;
+                }
 
-        // We need to grab the touch focus so that the touch events during the
-        // resizing/scrolling are not sent to the app. 'win' is the main window
-        // of the app, it may not have focus since there might be other windows
-        // on top (eg. a dialog window).
-        WindowState transferFocusFromWin = win;
-        if (displayContent.mCurrentFocus != null && displayContent.mCurrentFocus != win
-                && displayContent.mCurrentFocus.mActivityRecord == win.mActivityRecord) {
-            transferFocusFromWin = displayContent.mCurrentFocus;
-        }
-        if (!mService.mInputManager.transferTouchFocus(
-                transferFocusFromWin.mInputChannel, mTaskPositioner.mClientChannel,
-                false /* isDragDrop */)) {
-            Slog.e(TAG_WM, "startPositioningLocked: Unable to transfer touch focus");
-            cleanUpTaskPositioner();
-            return false;
-        }
-
-        mTaskPositioner.startDrag(resize, preserveOrientation, startX, startY);
-        return true;
+                mTaskPositioner.startDrag(resize, preserveOrientation, startX, startY);
+                return true;
+            }
+        });
     }
 
     public void finishTaskPositioning(IWindow window) {
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..a02be25 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();
@@ -443,23 +460,26 @@
      * Collects the window containers which need to be synced with the changing display (e.g.
      * rotating) to the given transition or the current collecting transition.
      */
-    void collectForDisplayChange(@NonNull DisplayContent dc, @Nullable Transition incoming) {
+    void collectForDisplayAreaChange(@NonNull DisplayArea<?> wc, @Nullable Transition incoming) {
         if (incoming == null) incoming = mCollectingTransition;
         if (incoming == null) return;
         final Transition transition = incoming;
         // Collect all visible tasks.
-        dc.forAllLeafTasks(task -> {
+        wc.forAllLeafTasks(task -> {
             if (task.isVisible()) {
                 transition.collect(task);
             }
         }, true /* traverseTopToBottom */);
         // Collect all visible non-app windows which need to be drawn before the animation starts.
-        dc.forAllWindows(w -> {
-            if (w.mActivityRecord == null && w.isVisible() && !isCollecting(w.mToken)
-                    && dc.shouldSyncRotationChange(w)) {
-                transition.collect(w.mToken);
-            }
-        }, true /* traverseTopToBottom */);
+        final DisplayContent dc = wc.asDisplayContent();
+        if (dc != null) {
+            wc.forAllWindows(w -> {
+                if (w.mActivityRecord == null && w.isVisible() && !isCollecting(w.mToken)
+                        && dc.shouldSyncRotationChange(w)) {
+                    transition.collect(w.mToken);
+                }
+            }, true /* traverseTopToBottom */);
+        }
     }
 
     /** @see Transition#mStatusBarTransitionDelay */
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 24a478e..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);
@@ -3756,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/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 9eee7ba..6121ad4 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -50,6 +50,7 @@
 import java.lang.annotation.Retention;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 
 /**
  * Window manager local system service interface.
@@ -303,12 +304,13 @@
      * An interface to customize drag and drop behaviors.
      */
     public interface IDragDropCallback {
-        default boolean registerInputChannel(
+        default CompletableFuture<Boolean> registerInputChannel(
                 DragState state, Display display, InputManagerService service,
                 InputChannel source) {
-            state.register(display);
-            return service.transferTouchFocus(source, state.getInputChannel(),
-                    true /* isDragDrop */);
+            return state.register(display)
+                .thenApply(unused ->
+                    service.transferTouchFocus(source, state.getInputChannel(),
+                            true /* isDragDrop */));
         }
 
         /**
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 6ffddd9..440a91a 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;
@@ -345,6 +344,8 @@
 import java.util.NoSuchElementException;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.function.Function;
 import java.util.function.Supplier;
 
@@ -375,6 +376,8 @@
     // proceding with safe mode detection.
     private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
 
+    private static final int SYNC_INPUT_TRANSACTIONS_TIMEOUT_MS = 5000;
+
     // Poll interval in milliseconds for watching boot animation finished.
     // TODO(b/159045990) Migrate to SystemService.waitForState with dedicated thread.
     private static final int BOOT_ANIMATION_POLL_INTERVAL = 50;
@@ -652,7 +655,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 +790,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(
@@ -1050,8 +1051,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 +1205,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 +2133,6 @@
     }
 
     void clearTouchableRegion(Session session, IWindow client) {
-        int uid = Binder.getCallingUid();
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
@@ -2304,12 +2308,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 +2544,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 +3822,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 +4319,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 +5638,7 @@
     }
 
     public boolean useBLASTSync() {
-        return mUseBLASTSync;
+        return USE_BLAST_SYNC;
     }
 
     @Override
@@ -5784,7 +5784,9 @@
                 final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
                 if (displayContent != null) {
                     displayContent.setForcedSize(displayContent.mInitialDisplayWidth,
-                            displayContent.mInitialDisplayHeight);
+                            displayContent.mInitialDisplayHeight,
+                            displayContent.mInitialPhysicalXDpi,
+                            displayContent.mInitialPhysicalXDpi);
                 }
             }
         } finally {
@@ -6498,12 +6500,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 +6531,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 +6596,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 +6611,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 +6628,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 +6735,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 +6758,7 @@
             }
         }
 
-        if (windows.size() <= 0) {
+        if (windows.isEmpty()) {
             return false;
         }
 
@@ -6888,17 +6889,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 +6946,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 +6966,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 +8257,7 @@
                         .setContainerLayer()
                         .setName("IME Handwriting Surface")
                         .setCallsite("getHandwritingSurfaceForDisplay")
-                        .setParent(dc.getOverlayLayer())
+                        .setParent(dc.getSurfaceControl())
                         .build();
             }
         }
@@ -8445,7 +8446,12 @@
                         displayContent.getInputMonitor().updateInputWindowsImmediately(t));
             }
 
-            t.syncInputWindows().apply();
+            CountDownLatch countDownLatch = new CountDownLatch(1);
+            t.addWindowInfosReportedListener(countDownLatch::countDown).apply();
+            countDownLatch.await(SYNC_INPUT_TRANSACTIONS_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException exception) {
+            Slog.e(TAG_WM, "Exception thrown while waiting for window infos to be reported",
+                    exception);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 4bbb1b1..d979753 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -397,7 +397,7 @@
                     // Go through all tasks and collect them before the rotation
                     // TODO(shell-transitions): move collect() to onConfigurationChange once
                     //       wallpaper handling is synchronized.
-                    dc.mTransitionController.collectForDisplayChange(dc, transition);
+                    dc.mTransitionController.collectForDisplayAreaChange(dc, transition);
                     dc.sendNewConfiguration();
                     effects |= TRANSACT_EFFECTS_LIFECYCLE;
                 }
@@ -421,6 +421,15 @@
                     addToSyncSet(syncId, wc);
                 }
                 if (transition != null) transition.collect(wc);
+                final DisplayArea da = wc.asDisplayArea();
+                // Only check DisplayArea here as a similar thing is done for DisplayContent above.
+                if (da != null && wc.asDisplayContent() == null
+                        && entry.getValue().getWindowingMode() != da.getWindowingMode()) {
+                    // Go through all tasks and collect them before changing the windowing mode of a
+                    // display-level container.
+                    // TODO(shell-transitions): handle this more elegantly.
+                    da.mTransitionController.collectForDisplayAreaChange(da, transition);
+                }
 
                 if ((entry.getValue().getChangeMask()
                         & WindowContainerTransaction.Change.CHANGE_FORCE_NO_PIP) != 0) {
@@ -755,7 +764,7 @@
                                     bottomActivity)) {
                         Slog.w(TAG, "Skip removing TaskFragment due in lock task mode.");
                         sendTaskFragmentOperationFailure(organizer, errorCallbackToken,
-                                new IllegalStateException(
+                                taskFragment, type, new IllegalStateException(
                                         "Not allow to delete task fragment in lock task mode."));
                         break;
                     }
@@ -769,13 +778,15 @@
                 if (tf == null) {
                     final Throwable exception = new IllegalArgumentException(
                             "Not allowed to operate with invalid fragment token");
-                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf, type,
+                            exception);
                     break;
                 }
                 if (tf.isEmbeddedTaskFragmentInPip()) {
                     final Throwable exception = new IllegalArgumentException(
                             "Not allowed to start activity in PIP TaskFragment");
-                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf, type,
+                            exception);
                     break;
                 }
                 final Intent activityIntent = hop.getActivityIntent();
@@ -785,7 +796,7 @@
                                 hop.getCallingActivity(), caller.mUid, caller.mPid,
                                 errorCallbackToken);
                 if (!isStartResultSuccessful(result)) {
-                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken,
+                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf, type,
                             convertStartFailureToThrowable(result, activityIntent));
                 } else {
                     effects |= TRANSACT_EFFECTS_LIFECYCLE;
@@ -806,25 +817,29 @@
                 if (parent == null || activity == null) {
                     final Throwable exception = new IllegalArgumentException(
                             "Not allowed to operate with invalid fragment token or activity.");
-                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, parent, type,
+                            exception);
                     break;
                 }
                 if (parent.isEmbeddedTaskFragmentInPip()) {
                     final Throwable exception = new IllegalArgumentException(
                             "Not allowed to reparent activity to PIP TaskFragment");
-                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, parent, type,
+                            exception);
                     break;
                 }
                 if (parent.isAllowedToEmbedActivity(activity) != EMBEDDING_ALLOWED) {
                     final Throwable exception = new SecurityException(
                             "The task fragment is not allowed to embed the given activity.");
-                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, parent, type,
+                            exception);
                     break;
                 }
                 if (parent.getTask() != activity.getTask()) {
                     final Throwable exception = new SecurityException("The reparented activity is"
                             + " not in the same Task as the target TaskFragment.");
-                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, parent, type,
+                            exception);
                     break;
                 }
 
@@ -842,14 +857,16 @@
                 if (tf1 == null || (adjacentFragmentToken != null && tf2 == null)) {
                     final Throwable exception = new IllegalArgumentException(
                             "Not allowed to set adjacent on invalid fragment tokens");
-                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf1, type,
+                            exception);
                     break;
                 }
                 if (tf1.isEmbeddedTaskFragmentInPip()
                         || (tf2 != null && tf2.isEmbeddedTaskFragmentInPip())) {
                     final Throwable exception = new IllegalArgumentException(
                             "Not allowed to set adjacent on TaskFragment in PIP Task");
-                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+                    sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf1, type,
+                            exception);
                     break;
                 }
                 tf1.setAdjacentTaskFragment(tf2);
@@ -1062,7 +1079,7 @@
                 + taskFragment.getBounds() + " does not satisfy minimum dimensions:"
                 + minDimensions + " " + reason);
         sendTaskFragmentOperationFailure(taskFragment.getTaskFragmentOrganizer(),
-                errorCallbackToken, exception);
+                errorCallbackToken, taskFragment, -1 /* opType */, exception);
     }
 
     /**
@@ -1235,8 +1252,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)) {
@@ -1611,13 +1632,15 @@
         if (ownerActivity == null || ownerActivity.getTask() == null) {
             final Throwable exception =
                     new IllegalArgumentException("Not allowed to operate with invalid ownerToken");
-            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
+                    HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
             return;
         }
         if (!ownerActivity.isResizeable()) {
             final IllegalArgumentException exception = new IllegalArgumentException("Not allowed"
                     + " to operate with non-resizable owner Activity");
-            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
+                    HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
             return;
         }
         // The ownerActivity has to belong to the same app as the target Task.
@@ -1627,13 +1650,15 @@
             final Throwable exception =
                     new SecurityException("Not allowed to operate with the ownerToken while "
                             + "the root activity of the target task belong to the different app");
-            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
+                    HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
             return;
         }
         if (ownerTask.inPinnedWindowingMode()) {
             final Throwable exception = new IllegalArgumentException(
                     "Not allowed to create TaskFragment in PIP Task");
-            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
+                    HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
             return;
         }
         final TaskFragment taskFragment = new TaskFragment(mService,
@@ -1661,7 +1686,8 @@
         if (newParentTF == null) {
             final Throwable exception =
                     new IllegalArgumentException("Not allowed to operate with invalid container");
-            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, newParentTF,
+                    HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
             return;
         }
         if (newParentTF.getTaskFragmentOrganizer() != null) {
@@ -1672,20 +1698,23 @@
             if (isEmbeddingDisallowed) {
                 final Throwable exception = new SecurityException(
                         "The new parent is not allowed to embed the activities.");
-                sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+                sendTaskFragmentOperationFailure(organizer, errorCallbackToken, newParentTF,
+                        HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
                 return;
             }
         }
         if (newParentTF.isEmbeddedTaskFragmentInPip() || oldParent.isEmbeddedTaskFragmentInPip()) {
             final Throwable exception = new SecurityException(
                     "Not allow to reparent in TaskFragment in PIP Task.");
-            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, newParentTF,
+                    HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
             return;
         }
         if (newParentTF.getTask() != oldParent.getTask()) {
             final Throwable exception = new SecurityException(
                     "The new parent is not in the same Task as the old parent.");
-            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, newParentTF,
+                    HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
             return;
         }
         while (oldParent.hasChild()) {
@@ -1700,7 +1729,8 @@
             final Throwable exception =
                     new IllegalArgumentException("Not allowed to operate with invalid "
                             + "taskFragment");
-            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+                    HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT, exception);
             return 0;
         }
         if (taskFragment.isEmbeddedTaskFragmentInPip()
@@ -1709,7 +1739,8 @@
                 && taskFragment.getTopNonFinishingActivity() != null) {
             final Throwable exception = new IllegalArgumentException(
                     "Not allowed to delete TaskFragment in PIP Task");
-            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
+            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+                    HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT, exception);
             return 0;
         }
         mLaunchTaskFragments.removeAt(index);
@@ -1737,12 +1768,14 @@
     }
 
     void sendTaskFragmentOperationFailure(@NonNull ITaskFragmentOrganizer organizer,
-            @Nullable IBinder errorCallbackToken, @NonNull Throwable exception) {
+            @Nullable IBinder errorCallbackToken, @Nullable TaskFragment taskFragment, int opType,
+            @NonNull Throwable exception) {
         if (organizer == null) {
             throw new IllegalArgumentException("Not allowed to operate with invalid organizer");
         }
         mService.mTaskFragmentOrganizerController
-                .onTaskFragmentError(organizer, errorCallbackToken, exception);
+                .onTaskFragmentError(organizer, errorCallbackToken, taskFragment, opType,
+                        exception);
     }
 
     private Throwable convertStartFailureToThrowable(int result, Intent intent) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 46091d8..3ef4aae 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);
     }
@@ -2449,8 +2448,8 @@
 
         final DisplayContent dc = getDisplayContent();
         if (isImeLayeringTarget()) {
-            // Remove the IME screenshot surface if the layering target is not animating.
-            dc.removeImeScreenshotIfPossible();
+            // Remove the attached IME screenshot surface.
+            dc.removeImeSurfaceByTarget(this);
             // Make sure to set mImeLayeringTarget as null when the removed window is the
             // IME target, in case computeImeTarget may use the outdated target.
             dc.setImeLayeringTarget(null);
@@ -3461,10 +3460,6 @@
         return mClient.asBinder().isBinderAlive();
     }
 
-    boolean isClosing() {
-        return mAnimatingExit || (mActivityRecord != null && mActivityRecord.isClosingOrEnteringPip());
-    }
-
     void sendAppVisibilityToClients() {
         super.sendAppVisibilityToClients();
 
@@ -3588,6 +3583,7 @@
         } else {
             logExclusionRestrictions(EXCLUSION_LEFT);
             logExclusionRestrictions(EXCLUSION_RIGHT);
+            getDisplayContent().removeImeSurfaceByTarget(this);
         }
         // Exclude toast because legacy apps may show toast window by themselves, so the misused
         // apps won't always be considered as foreground state.
@@ -4703,19 +4699,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 +5472,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/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 4c2803f..b4cade3 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -18618,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/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/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 7e251d0..102d17c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -74,7 +74,6 @@
 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_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;
@@ -721,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);
@@ -2337,10 +2355,15 @@
         mBinder.set(TEST_CALLING_PACKAGE, RTC_WAKEUP, 1234, WINDOW_EXACT, 0, 0,
                 alarmPi, null, null, null, alarmClock);
 
+        final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
         verify(mService).setImpl(eq(RTC_WAKEUP), eq(1234L), eq(WINDOW_EXACT), eq(0L),
                 eq(alarmPi), isNull(), isNull(), eq(FLAG_STANDALONE | FLAG_WAKE_FROM_IDLE),
-                isNull(), eq(alarmClock), eq(TEST_CALLING_UID), eq(TEST_CALLING_PACKAGE), isNull(),
-                eq(EXACT_ALLOW_REASON_COMPAT));
+                isNull(), eq(alarmClock), eq(TEST_CALLING_UID), eq(TEST_CALLING_PACKAGE),
+                bundleCaptor.capture(), eq(EXACT_ALLOW_REASON_COMPAT));
+
+        final BroadcastOptions idleOptions = new BroadcastOptions(bundleCaptor.getValue());
+        final int type = idleOptions.getTemporaryAppAllowlistType();
+        assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, type);
     }
 
     @Test
@@ -3074,37 +3097,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/BatteryControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/BatteryControllerTest.java
index 52d0494..2f61908 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/BatteryControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/BatteryControllerTest.java
@@ -312,4 +312,71 @@
         assertFalse(jobLateFg.isConstraintSatisfied(JobStatus.CONSTRAINT_CHARGING));
         assertFalse(jobLateFgLow.isConstraintSatisfied(JobStatus.CONSTRAINT_CHARGING));
     }
+
+    @Test
+    public void testControllerOnlyTracksPowerJobs() {
+        JobStatus batteryJob = createJobStatus("testControllerOnlyTracksPowerJobs",
+                SOURCE_PACKAGE, mSourceUid,
+                createBaseJobInfoBuilder(1).setRequiresBatteryNotLow(true).build());
+        JobStatus chargingJob = createJobStatus("testControllerOnlyTracksPowerJobs",
+                SOURCE_PACKAGE, mSourceUid,
+                createBaseJobInfoBuilder(2).setRequiresCharging(true).build());
+        JobStatus bothPowerJob = createJobStatus("testControllerOnlyTracksPowerJobs",
+                SOURCE_PACKAGE, mSourceUid,
+                createBaseJobInfoBuilder(3)
+                        .setRequiresCharging(true)
+                        .setRequiresBatteryNotLow(true)
+                        .build());
+        JobStatus unrelatedJob = createJobStatus("testControllerOnlyTracksPowerJobs",
+                SOURCE_PACKAGE, mSourceUid, createBaseJobInfoBuilder(4).build());
+
+        // Follow the lifecycle of tracking
+        // Start tracking
+        trackJobs(batteryJob, chargingJob, bothPowerJob, unrelatedJob);
+        final ArraySet<JobStatus> trackedJobs = mBatteryController.getTrackedJobs();
+        final ArraySet<JobStatus> topStartedJobs = mBatteryController.getTopStartedJobs();
+        assertTrue(trackedJobs.contains(batteryJob));
+        assertTrue(trackedJobs.contains(chargingJob));
+        assertTrue(trackedJobs.contains(bothPowerJob));
+        assertFalse(trackedJobs.contains(unrelatedJob));
+        assertFalse(topStartedJobs.contains(batteryJob));
+        assertFalse(topStartedJobs.contains(chargingJob));
+        assertFalse(topStartedJobs.contains(bothPowerJob));
+        assertFalse(topStartedJobs.contains(unrelatedJob));
+
+        // Procstate change shouldn't affect anything
+        setUidBias(mSourceUid, JobInfo.BIAS_TOP_APP);
+        assertTrue(trackedJobs.contains(batteryJob));
+        assertTrue(trackedJobs.contains(chargingJob));
+        assertTrue(trackedJobs.contains(bothPowerJob));
+        assertFalse(trackedJobs.contains(unrelatedJob));
+        assertFalse(topStartedJobs.contains(batteryJob));
+        assertFalse(topStartedJobs.contains(chargingJob));
+        assertFalse(topStartedJobs.contains(bothPowerJob));
+        assertFalse(topStartedJobs.contains(unrelatedJob));
+
+        // Job starts running
+        mBatteryController.prepareForExecutionLocked(batteryJob);
+        mBatteryController.prepareForExecutionLocked(chargingJob);
+        mBatteryController.prepareForExecutionLocked(bothPowerJob);
+        mBatteryController.prepareForExecutionLocked(unrelatedJob);
+        assertTrue(topStartedJobs.contains(batteryJob));
+        assertTrue(topStartedJobs.contains(chargingJob));
+        assertTrue(topStartedJobs.contains(bothPowerJob));
+        assertFalse(topStartedJobs.contains(unrelatedJob));
+
+        // Job cleanup
+        mBatteryController.maybeStopTrackingJobLocked(batteryJob, null, false);
+        mBatteryController.maybeStopTrackingJobLocked(chargingJob, null, false);
+        mBatteryController.maybeStopTrackingJobLocked(bothPowerJob, null, false);
+        mBatteryController.maybeStopTrackingJobLocked(unrelatedJob, null, false);
+        assertFalse(trackedJobs.contains(batteryJob));
+        assertFalse(trackedJobs.contains(chargingJob));
+        assertFalse(trackedJobs.contains(bothPowerJob));
+        assertFalse(trackedJobs.contains(unrelatedJob));
+        assertFalse(topStartedJobs.contains(batteryJob));
+        assertFalse(topStartedJobs.contains(chargingJob));
+        assertFalse(topStartedJobs.contains(bothPowerJob));
+        assertFalse(topStartedJobs.contains(unrelatedJob));
+    }
 }
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/job/restrictions/ThermalStatusRestrictionTest.java b/services/tests/mockingservicestests/src/com/android/server/job/restrictions/ThermalStatusRestrictionTest.java
index ab08573..aa95916 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/restrictions/ThermalStatusRestrictionTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/restrictions/ThermalStatusRestrictionTest.java
@@ -33,6 +33,8 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
@@ -111,42 +113,46 @@
         InOrder inOrder = inOrder(mJobSchedulerService);
 
         mStatusChangedListener.onThermalStatusChanged(THERMAL_STATUS_NONE);
-        inOrder.verify(mJobSchedulerService, never()).onControllerStateChanged(any());
+        inOrder.verify(mJobSchedulerService, never())
+                .onRestrictionStateChanged(any(), anyBoolean());
         assertEquals(THERMAL_STATUS_NONE, mThermalStatusRestriction.getThermalStatus());
 
         // Moving within LOW and UPPER thresholds
         mStatusChangedListener.onThermalStatusChanged(THERMAL_STATUS_LIGHT);
-        inOrder.verify(mJobSchedulerService).onControllerStateChanged(any());
+        inOrder.verify(mJobSchedulerService).onRestrictionStateChanged(any(), eq(true));
         assertEquals(THERMAL_STATUS_LIGHT, mThermalStatusRestriction.getThermalStatus());
 
         mStatusChangedListener.onThermalStatusChanged(THERMAL_STATUS_MODERATE);
-        inOrder.verify(mJobSchedulerService).onControllerStateChanged(any());
+        inOrder.verify(mJobSchedulerService).onRestrictionStateChanged(any(), eq(true));
         assertEquals(THERMAL_STATUS_MODERATE, mThermalStatusRestriction.getThermalStatus());
 
         mStatusChangedListener.onThermalStatusChanged(THERMAL_STATUS_SEVERE);
-        inOrder.verify(mJobSchedulerService).onControllerStateChanged(any());
+        inOrder.verify(mJobSchedulerService).onRestrictionStateChanged(any(), eq(true));
         assertEquals(THERMAL_STATUS_SEVERE, mThermalStatusRestriction.getThermalStatus());
 
         // Changing outside of range
         mStatusChangedListener.onThermalStatusChanged(THERMAL_STATUS_CRITICAL);
-        inOrder.verify(mJobSchedulerService, never()).onControllerStateChanged(any());
+        inOrder.verify(mJobSchedulerService, never())
+                .onRestrictionStateChanged(any(), eq(true));
         assertEquals(THERMAL_STATUS_CRITICAL, mThermalStatusRestriction.getThermalStatus());
 
         mStatusChangedListener.onThermalStatusChanged(THERMAL_STATUS_EMERGENCY);
-        inOrder.verify(mJobSchedulerService, never()).onControllerStateChanged(any());
+        inOrder.verify(mJobSchedulerService, never())
+                .onRestrictionStateChanged(any(), anyBoolean());
         assertEquals(THERMAL_STATUS_EMERGENCY, mThermalStatusRestriction.getThermalStatus());
 
         mStatusChangedListener.onThermalStatusChanged(THERMAL_STATUS_SHUTDOWN);
-        inOrder.verify(mJobSchedulerService, never()).onControllerStateChanged(any());
+        inOrder.verify(mJobSchedulerService, never())
+                .onRestrictionStateChanged(any(), anyBoolean());
         assertEquals(THERMAL_STATUS_SHUTDOWN, mThermalStatusRestriction.getThermalStatus());
 
         // Cross values we care about
         mStatusChangedListener.onThermalStatusChanged(THERMAL_STATUS_NONE);
-        inOrder.verify(mJobSchedulerService).onControllerStateChanged(any());
+        inOrder.verify(mJobSchedulerService).onRestrictionStateChanged(any(), eq(false));
         assertEquals(THERMAL_STATUS_NONE, mThermalStatusRestriction.getThermalStatus());
 
         mStatusChangedListener.onThermalStatusChanged(THERMAL_STATUS_EMERGENCY);
-        inOrder.verify(mJobSchedulerService).onControllerStateChanged(any());
+        inOrder.verify(mJobSchedulerService).onRestrictionStateChanged(any(), eq(true));
         assertEquals(THERMAL_STATUS_EMERGENCY, mThermalStatusRestriction.getThermalStatus());
     }
 
@@ -160,12 +166,16 @@
                 createJobBuilder(2).setPriority(JobInfo.PRIORITY_LOW).build());
         final JobStatus jobLowPriorityRunning = createJobStatus("testIsJobRestricted",
                 createJobBuilder(3).setPriority(JobInfo.PRIORITY_LOW).build());
+        final JobStatus jobLowPriorityRunningLong = createJobStatus("testIsJobRestricted",
+                createJobBuilder(9).setPriority(JobInfo.PRIORITY_LOW).build());
         final JobStatus jobDefaultPriority = createJobStatus("testIsJobRestricted",
                 createJobBuilder(4).setPriority(JobInfo.PRIORITY_DEFAULT).build());
         final JobStatus jobHighPriority = createJobStatus("testIsJobRestricted",
                 createJobBuilder(5).setPriority(JobInfo.PRIORITY_HIGH).build());
         final JobStatus jobHighPriorityRunning = createJobStatus("testIsJobRestricted",
                 createJobBuilder(6).setPriority(JobInfo.PRIORITY_HIGH).build());
+        final JobStatus jobHighPriorityRunningLong = createJobStatus("testIsJobRestricted",
+                createJobBuilder(10).setPriority(JobInfo.PRIORITY_HIGH).build());
         final JobStatus ejDowngraded = createJobStatus("testIsJobRestricted",
                 createJobBuilder(7).setExpedited(true).build());
         final JobStatus ej = spy(createJobStatus("testIsJobRestricted",
@@ -174,13 +184,17 @@
         when(mJobSchedulerService.isCurrentlyRunningLocked(jobLowPriorityRunning)).thenReturn(true);
         when(mJobSchedulerService.isCurrentlyRunningLocked(jobHighPriorityRunning))
                 .thenReturn(true);
+        when(mJobSchedulerService.isLongRunningLocked(jobLowPriorityRunningLong)).thenReturn(true);
+        when(mJobSchedulerService.isLongRunningLocked(jobHighPriorityRunningLong)).thenReturn(true);
 
         assertFalse(mThermalStatusRestriction.isJobRestricted(jobMinPriority));
         assertFalse(mThermalStatusRestriction.isJobRestricted(jobLowPriority));
         assertFalse(mThermalStatusRestriction.isJobRestricted(jobLowPriorityRunning));
+        assertFalse(mThermalStatusRestriction.isJobRestricted(jobLowPriorityRunningLong));
         assertFalse(mThermalStatusRestriction.isJobRestricted(jobDefaultPriority));
         assertFalse(mThermalStatusRestriction.isJobRestricted(jobHighPriority));
         assertFalse(mThermalStatusRestriction.isJobRestricted(jobHighPriorityRunning));
+        assertFalse(mThermalStatusRestriction.isJobRestricted(jobHighPriorityRunningLong));
         assertFalse(mThermalStatusRestriction.isJobRestricted(ej));
         assertFalse(mThermalStatusRestriction.isJobRestricted(ejDowngraded));
 
@@ -189,9 +203,11 @@
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobMinPriority));
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobLowPriority));
         assertFalse(mThermalStatusRestriction.isJobRestricted(jobLowPriorityRunning));
+        assertTrue(mThermalStatusRestriction.isJobRestricted(jobLowPriorityRunningLong));
         assertFalse(mThermalStatusRestriction.isJobRestricted(jobDefaultPriority));
         assertFalse(mThermalStatusRestriction.isJobRestricted(jobHighPriority));
         assertFalse(mThermalStatusRestriction.isJobRestricted(jobHighPriorityRunning));
+        assertFalse(mThermalStatusRestriction.isJobRestricted(jobHighPriorityRunningLong));
         assertFalse(mThermalStatusRestriction.isJobRestricted(ejDowngraded));
         assertFalse(mThermalStatusRestriction.isJobRestricted(ej));
 
@@ -200,9 +216,11 @@
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobMinPriority));
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobLowPriority));
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobLowPriorityRunning));
+        assertTrue(mThermalStatusRestriction.isJobRestricted(jobLowPriorityRunningLong));
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobDefaultPriority));
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobHighPriority));
         assertFalse(mThermalStatusRestriction.isJobRestricted(jobHighPriorityRunning));
+        assertTrue(mThermalStatusRestriction.isJobRestricted(jobHighPriorityRunningLong));
         assertTrue(mThermalStatusRestriction.isJobRestricted(ejDowngraded));
         assertFalse(mThermalStatusRestriction.isJobRestricted(ej));
 
@@ -211,9 +229,11 @@
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobMinPriority));
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobLowPriority));
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobLowPriorityRunning));
+        assertTrue(mThermalStatusRestriction.isJobRestricted(jobLowPriorityRunningLong));
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobDefaultPriority));
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobHighPriority));
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobHighPriorityRunning));
+        assertTrue(mThermalStatusRestriction.isJobRestricted(jobHighPriorityRunningLong));
         assertTrue(mThermalStatusRestriction.isJobRestricted(ejDowngraded));
         assertTrue(mThermalStatusRestriction.isJobRestricted(ej));
 
@@ -222,9 +242,11 @@
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobMinPriority));
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobLowPriority));
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobLowPriorityRunning));
+        assertTrue(mThermalStatusRestriction.isJobRestricted(jobLowPriorityRunningLong));
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobDefaultPriority));
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobHighPriority));
         assertTrue(mThermalStatusRestriction.isJobRestricted(jobHighPriorityRunning));
+        assertTrue(mThermalStatusRestriction.isJobRestricted(jobHighPriorityRunningLong));
         assertTrue(mThermalStatusRestriction.isJobRestricted(ejDowngraded));
         assertTrue(mThermalStatusRestriction.isJobRestricted(ej));
     }
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/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/DisplayDeviceConfigTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
new file mode 100644
index 0000000..7939303
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.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 com.android.server.display;
+
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public final class DisplayDeviceConfigTest {
+    private DisplayDeviceConfig mDisplayDeviceConfig;
+    @Mock
+    private Context mContext;
+
+    @Mock
+    private Resources mResources;
+
+    @Before
+    public void setUp() throws IOException {
+        MockitoAnnotations.initMocks(this);
+        when(mContext.getResources()).thenReturn(mResources);
+        mockDeviceConfigs();
+        try {
+            Path tempFile = Files.createTempFile("display_config", ".tmp");
+            Files.write(tempFile, getContent().getBytes(StandardCharsets.UTF_8));
+            mDisplayDeviceConfig = new DisplayDeviceConfig(mContext);
+            mDisplayDeviceConfig.initFromFile(tempFile.toFile());
+        } catch (IOException e) {
+            throw new IOException("Failed to setup the display device config.", e);
+        }
+    }
+
+    @Test
+    public void testConfigValues() {
+        assertEquals(mDisplayDeviceConfig.getAmbientHorizonLong(), 5000);
+        assertEquals(mDisplayDeviceConfig.getAmbientHorizonShort(), 50);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis(), 3000);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampIncreaseMaxMillis(), 2000);
+        assertEquals(mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold(), 10.0f, 0.0f);
+        assertEquals(mDisplayDeviceConfig.getAmbientLuxDarkeningMinThreshold(), 2.0f, 0.0f);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampFastDecrease(), 0.01f, 0.0f);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampFastIncrease(), 0.02f, 0.0f);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowIncrease(), 0.04f, 0.0f);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowDecrease(), 0.03f, 0.0f);
+        assertEquals(mDisplayDeviceConfig.getBrightnessDefault(), 0.5f, 0.0f);
+        assertArrayEquals(mDisplayDeviceConfig.getBrightness(), new float[]{0.0f, 0.62f, 1.0f},
+                0.0f);
+        assertArrayEquals(mDisplayDeviceConfig.getNits(), new float[]{2.0f, 500.0f, 800.0f}, 0.0f);
+        assertArrayEquals(mDisplayDeviceConfig.getBacklight(), new float[]{0.0f, 0.62f, 1.0f},
+                0.0f);
+        assertEquals(mDisplayDeviceConfig.getScreenBrighteningMinThreshold(), 0.001, 0.000001f);
+        assertEquals(mDisplayDeviceConfig.getScreenDarkeningMinThreshold(), 0.002, 0.000001f);
+
+        // Todo(brup): Add asserts for BrightnessThrottlingData, DensityMapping,
+        // HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
+        // Also add test for the case where optional display configs are null
+    }
+
+    private String getContent() {
+        return "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                + "<displayConfiguration>\n"
+                +   "<screenBrightnessMap>\n"
+                +       "<point>\n"
+                +           "<value>0.0</value>\n"
+                +           "<nits>2.0</nits>\n"
+                +       "</point>\n"
+                +       "<point>\n"
+                +           "<value>0.62</value>\n"
+                +           "<nits>500.0</nits>\n"
+                +       "</point>\n"
+                +       "<point>\n"
+                +           "<value>1.0</value>\n"
+                +           "<nits>800.0</nits>\n"
+                +       "</point>\n"
+                +   "</screenBrightnessMap>\n"
+                +   "<highBrightnessMode enabled=\"true\">\n"
+                +       "<transitionPoint>0.62</transitionPoint>\n"
+                +       "<minimumLux>10000</minimumLux>\n"
+                +       "<timing>\n"
+                +           "<!-- allow for 5 minutes out of every 30 minutes -->\n"
+                +           "<timeWindowSecs>1800</timeWindowSecs>\n"
+                +           "<timeMaxSecs>300</timeMaxSecs>\n"
+                +           "<timeMinSecs>60</timeMinSecs>\n"
+                +       "</timing>\n"
+                +       "<refreshRate>\n"
+                +           "<minimum>120</minimum>\n"
+                +           "<maximum>120</maximum>\n"
+                +       "</refreshRate>\n"
+                +       "<thermalStatusLimit>light</thermalStatusLimit>\n"
+                +       "<allowInLowPowerMode>false</allowInLowPowerMode>\n"
+                +   "</highBrightnessMode>\n"
+                +   "<ambientBrightnessChangeThresholds>\n"
+                +       "<brighteningThresholds>\n"
+                +           "<minimum>10</minimum>\n"
+                +       "</brighteningThresholds>\n"
+                +       "<darkeningThresholds>\n"
+                +           "<minimum>2</minimum>\n"
+                +       "</darkeningThresholds>\n"
+                +   "</ambientBrightnessChangeThresholds>\n"
+                +   "<screenBrightnessRampFastDecrease>0.01</screenBrightnessRampFastDecrease> "
+                +   "<screenBrightnessRampFastIncrease>0.02</screenBrightnessRampFastIncrease>  "
+                +   "<screenBrightnessRampSlowDecrease>0.03</screenBrightnessRampSlowDecrease>"
+                +   "<screenBrightnessRampSlowIncrease>0.04</screenBrightnessRampSlowIncrease>"
+                +   "<screenBrightnessRampIncreaseMaxMillis>"
+                +       "2000"
+                +   "</screenBrightnessRampIncreaseMaxMillis>"
+                +   "<screenBrightnessRampDecreaseMaxMillis>"
+                +       "3000"
+                +   "</screenBrightnessRampDecreaseMaxMillis>"
+                +   "<ambientLightHorizonLong>5000</ambientLightHorizonLong>\n"
+                +   "<ambientLightHorizonShort>50</ambientLightHorizonShort>\n"
+                +   "<displayBrightnessChangeThresholds>"
+                +       "<brighteningThresholds>"
+                +           "<minimum>"
+                +               "0.001"
+                +           "</minimum>"
+                +       "</brighteningThresholds>"
+                +       "<darkeningThresholds>"
+                +           "<minimum>"
+                +               "0.002"
+                +           "</minimum>"
+                +       "</darkeningThresholds>"
+                +   "</displayBrightnessChangeThresholds>"
+                +   "<screenBrightnessRampIncreaseMaxMillis>"
+                +       "2000"
+                +    "</screenBrightnessRampIncreaseMaxMillis>\n"
+                +   "<thermalThrottling>\n"
+                +       "<brightnessThrottlingMap>\n"
+                +           "<brightnessThrottlingPoint>\n"
+                +               "<thermalStatus>emergency</thermalStatus>\n"
+                +               "<!-- Throttling to 250 nits: (250-2.0)/(500-2.0)*(0.62-0.0)+0"
+                +               ".0 = 0.30875502 -->\n"
+                +               "<brightness>0.30875502</brightness>\n"
+                +           "</brightnessThrottlingPoint>\n"
+                +       "</brightnessThrottlingMap>\n"
+                +   "</thermalThrottling>\n"
+                + "</displayConfiguration>\n";
+    }
+
+    private void mockDeviceConfigs() {
+        when(mResources.getFloat(com.android.internal.R.dimen
+                .config_screenBrightnessSettingDefaultFloat)).thenReturn(0.5f);
+        when(mResources.getFloat(com.android.internal.R.dimen
+                .config_screenBrightnessSettingMaximumFloat)).thenReturn(1.0f);
+    }
+}
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/display/brightness/BrightnessEventTest.java b/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessEventTest.java
new file mode 100644
index 0000000..e305957
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessEventTest.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 com.android.server.display.brightness;
+
+import static org.junit.Assert.assertEquals;
+
+import android.hardware.display.BrightnessInfo;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public final class BrightnessEventTest {
+    private BrightnessEvent mBrightnessEvent;
+
+    @Before
+    public void setUp() {
+        mBrightnessEvent = new BrightnessEvent(1);
+        mBrightnessEvent.setReason(
+                getReason(BrightnessReason.REASON_DOZE, BrightnessReason.MODIFIER_LOW_POWER));
+        mBrightnessEvent.setLux(100.0f);
+        mBrightnessEvent.setPreThresholdLux(150.0f);
+        mBrightnessEvent.setTime(System.currentTimeMillis());
+        mBrightnessEvent.setBrightness(0.6f);
+        mBrightnessEvent.setRecommendedBrightness(0.6f);
+        mBrightnessEvent.setHbmMax(0.62f);
+        mBrightnessEvent.setThermalMax(0.65f);
+        mBrightnessEvent.setHbmMode(BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF);
+        mBrightnessEvent.setFlags(0);
+        mBrightnessEvent.setAdjustmentFlags(0);
+    }
+
+    @Test
+    public void testEqualsMainDataComparesAllFieldsExceptTime() {
+        BrightnessEvent secondBrightnessEvent = new BrightnessEvent(1);
+        secondBrightnessEvent.copyFrom(mBrightnessEvent);
+        secondBrightnessEvent.setTime(0);
+        assertEquals(secondBrightnessEvent.equalsMainData(mBrightnessEvent), true);
+    }
+
+    @Test
+    public void testToStringWorksAsExpected() {
+        String actualString = mBrightnessEvent.toString(false);
+        String expectedString =
+                "BrightnessEvent: disp=1, brt=0.6, rcmdBrt=0.6, preBrt=NaN, lux=100.0, preLux=150"
+                        + ".0, hbmMax=0.62, hbmMode=off, thrmMax=0.65, flags=, reason=doze [ "
+                        + "low_pwr ]";
+        assertEquals(actualString, expectedString);
+    }
+
+    private BrightnessReason getReason(int reason, int modifier) {
+        BrightnessReason brightnessReason = new BrightnessReason();
+        brightnessReason.setReason(reason);
+        brightnessReason.setModifier(modifier);
+        return brightnessReason;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessReasonTest.java b/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessReasonTest.java
new file mode 100644
index 0000000..ffc2e0d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/brightness/BrightnessReasonTest.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.display.brightness;
+
+import static org.junit.Assert.assertEquals;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public final class BrightnessReasonTest {
+    private BrightnessReason mBrightnessReason;
+
+    @Before
+    public void setUp() {
+        mBrightnessReason = getReason(BrightnessReason.REASON_DOZE,
+                BrightnessReason.MODIFIER_LOW_POWER);
+    }
+
+    @Test
+    public void setSetsAppropriateValues() {
+        mBrightnessReason.set(null);
+        assertEquals(mBrightnessReason.getReason(), BrightnessReason.REASON_UNKNOWN);
+        assertEquals(mBrightnessReason.getModifier(), 0);
+
+        mBrightnessReason.set(
+                getReason(BrightnessReason.REASON_BOOST, BrightnessReason.MODIFIER_THROTTLED));
+        assertEquals(mBrightnessReason.getReason(), BrightnessReason.REASON_BOOST);
+        assertEquals(mBrightnessReason.getModifier(), BrightnessReason.MODIFIER_THROTTLED);
+    }
+
+    @Test
+    public void toStringGeneratesExpectedString() {
+        String actualString = mBrightnessReason.toString();
+        String expectedString = "doze [ low_pwr ]";
+        assertEquals(actualString, expectedString);
+    }
+
+    @Test
+    public void setModifierDoesntSetIfModifierIsBeyondExtremes() {
+        int extremeModifier = 0x16;
+        mBrightnessReason.setModifier(extremeModifier);
+        assertEquals(mBrightnessReason.getModifier(), BrightnessReason.MODIFIER_LOW_POWER);
+    }
+
+    @Test
+    public void setReasonDoesntSetIfModifierIsBeyondExtremes() {
+        int extremeReason = 10;
+        mBrightnessReason.setReason(extremeReason);
+        assertEquals(mBrightnessReason.getReason(), BrightnessReason.REASON_DOZE);
+
+        extremeReason = -1;
+        mBrightnessReason.setReason(extremeReason);
+        assertEquals(mBrightnessReason.getReason(), BrightnessReason.REASON_DOZE);
+    }
+
+    @Test
+    public void addModifierWorksAsExpected() {
+        mBrightnessReason.addModifier(BrightnessReason.REASON_BOOST);
+        assertEquals(mBrightnessReason.getModifier(),
+                BrightnessReason.REASON_DOZE | BrightnessReason.REASON_BOOST);
+    }
+
+    private BrightnessReason getReason(int reason, int modifier) {
+        BrightnessReason brightnessReason = new BrightnessReason();
+        brightnessReason.setReason(reason);
+        brightnessReason.setModifier(modifier);
+        return brightnessReason;
+    }
+}
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 c4df051..a663858 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
@@ -304,14 +304,15 @@
     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));
     }
 
@@ -319,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));
     }
 
@@ -327,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/locksettings/MockSyntheticPasswordManager.java b/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
index 5a3f12c..0bb2021 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
@@ -47,7 +47,7 @@
     private ArrayMap<String, byte[]> mBlobs = new ArrayMap<>();
 
     @Override
-    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
+    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] protectorSecret) {
         if (mBlobs.containsKey(blobKeyName) && !Arrays.equals(mBlobs.get(blobKeyName), blob)) {
             throw new AssertionFailedError("blobKeyName content is overwritten: " + blobKeyName);
         }
@@ -59,11 +59,11 @@
         byte[] data = new byte[len];
         buffer.get(data);
         len = buffer.getInt();
-        byte[] appId = new byte[len];
-        buffer.get(appId);
+        byte[] storedProtectorSecret = new byte[len];
+        buffer.get(storedProtectorSecret);
         long sid = buffer.getLong();
-        if (!Arrays.equals(appId, applicationId)) {
-            throw new AssertionFailedError("Invalid application id");
+        if (!Arrays.equals(storedProtectorSecret, protectorSecret)) {
+            throw new AssertionFailedError("Invalid protector secret");
         }
         if (sid != 0 && mGateKeeper.getAuthTokenForSid(sid) == null) {
             throw new AssertionFailedError("No valid auth token");
@@ -72,13 +72,14 @@
     }
 
     @Override
-    protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) {
+    protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] protectorSecret,
+            long sid) {
         ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + data.length + Integer.BYTES
-                + applicationId.length + Long.BYTES);
+                + protectorSecret.length + Long.BYTES);
         buffer.putInt(data.length);
         buffer.put(data);
-        buffer.putInt(applicationId.length);
-        buffer.put(applicationId);
+        buffer.putInt(protectorSecret.length);
+        buffer.put(protectorSecret);
         buffer.putLong(sid);
         byte[] result = buffer.array();
         mBlobs.put(blobKeyName, result);
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index 6d1df2c..87beece 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -19,7 +19,7 @@
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD_OR_PIN;
-import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
+import static com.android.internal.widget.LockPatternUtils.CURRENT_LSKF_BASED_PROTECTOR_ID_KEY;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -45,8 +45,8 @@
 import com.android.internal.widget.LockscreenCredential;
 import com.android.internal.widget.VerifyCredentialResponse;
 import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationResult;
-import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationToken;
 import com.android.server.locksettings.SyntheticPasswordManager.PasswordData;
+import com.android.server.locksettings.SyntheticPasswordManager.SyntheticPassword;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -74,28 +74,28 @@
     }
 
     @Test
-    public void testPasswordBasedSyntheticPassword() throws RemoteException {
+    public void testLskfBasedProtector() throws RemoteException {
         final int USER_ID = 10;
         final LockscreenCredential password = newPassword("user-password");
         final LockscreenCredential badPassword = newPassword("bad-password");
         MockSyntheticPasswordManager manager = new MockSyntheticPasswordManager(mContext, mStorage,
                 mGateKeeperService, mUserManager, mPasswordSlotManager);
-        AuthenticationToken authToken = manager.newSyntheticPassword(USER_ID);
-        long handle = manager.createPasswordBasedSyntheticPassword(mGateKeeperService,
-                password, authToken, USER_ID);
+        SyntheticPassword sp = manager.newSyntheticPassword(USER_ID);
+        long protectorId = manager.createLskfBasedProtector(mGateKeeperService, password, sp,
+                USER_ID);
 
-        AuthenticationResult result = manager.unwrapPasswordBasedSyntheticPassword(
-                mGateKeeperService, handle, password, USER_ID, null);
-        assertArrayEquals(result.authToken.deriveKeyStorePassword(),
-                authToken.deriveKeyStorePassword());
+        AuthenticationResult result = manager.unlockLskfBasedProtector(mGateKeeperService,
+                protectorId, password, USER_ID, null);
+        assertArrayEquals(result.syntheticPassword.deriveKeyStorePassword(),
+                sp.deriveKeyStorePassword());
 
-        result = manager.unwrapPasswordBasedSyntheticPassword(mGateKeeperService, handle,
-                badPassword, USER_ID, null);
-        assertNull(result.authToken);
+        result = manager.unlockLskfBasedProtector(mGateKeeperService, protectorId, badPassword,
+                USER_ID, null);
+        assertNull(result.syntheticPassword);
     }
 
     private boolean hasSyntheticPassword(int userId) throws RemoteException {
-        return mService.getLong(SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId) != 0;
+        return mService.getLong(CURRENT_LSKF_BASED_PROTECTOR_ID_KEY, 0, userId) != 0;
     }
 
     private void initializeCredential(LockscreenCredential password, int userId)
@@ -544,12 +544,12 @@
     }
 
     private void assertNoOrphanedFilesLeft(int userId) {
-        String handleString = String.format("%016x",
-                mService.getSyntheticPasswordHandleLocked(userId));
+        String lskfProtectorPrefix = String.format("%016x",
+                mService.getCurrentLskfBasedProtectorId(userId));
         File directory = mStorage.getSyntheticPasswordDirectoryForUser(userId);
         for (File file : directory.listFiles()) {
             String[] parts = file.getName().split("\\.");
-            if (!parts[0].equals(handleString) && !parts[0].equals("0000000000000000")) {
+            if (!parts[0].equals(lskfProtectorPrefix) && !parts[0].equals("0000000000000000")) {
                 fail("Orphaned state left: " + file.getName());
             }
         }
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/power/stats/BatteryStatsServTest.java b/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsServTest.java
index 7f6cf42..200eb1d 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsServTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsServTest.java
@@ -172,11 +172,6 @@
     public void testStartLaunchedLockedWhileLaunched() throws Exception  {
         MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() {
             @Override
-            public long getBatteryUptimeLocked() {
-                return 777777L * 1000; // microseconds
-            }
-
-            @Override
             public long getBatteryUptimeLocked(long uptimeMs) {
                 return 777777L * 1000; // microseconds
             }
@@ -206,11 +201,6 @@
     public void testStartLaunchedLockedWhileNotLaunched() throws Exception  {
         MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() {
             @Override
-            public long getBatteryUptimeLocked() {
-                return 777777L * 1000; // microseconds
-            }
-
-            @Override
             public long getBatteryUptimeLocked(long uptimeMs) {
                 return 777777L * 1000; // microseconds
             }
@@ -238,11 +228,6 @@
     public void testStopLaunchedLockedWhileNotLaunched() throws Exception  {
         MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() {
             @Override
-            public long getBatteryUptimeLocked() {
-                return 777777L * 1000; // microseconds
-            }
-
-            @Override
             public long getBatteryUptimeLocked(long uptimeMs) {
                 return 777777L * 1000; // microseconds
             }
@@ -273,11 +258,6 @@
     public void testStopLaunchedLockedWhileLaunchedNormal() throws Exception  {
         MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() {
             @Override
-            public long getBatteryUptimeLocked() {
-                return 777777L * 1000; // microseconds
-            }
-
-            @Override
             public long getBatteryUptimeLocked(long uptimeMs) {
                 return 777777L * 1000; // microseconds
             }
@@ -305,12 +285,7 @@
      */
     @SmallTest
     public void testStopLaunchedLockedWhileLaunchedTooQuick() throws Exception  {
-        MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() {
-            @Override
-            public long getBatteryUptimeLocked() {
-                return 6064L;
-            }
-        };
+        MockBatteryStatsImpl bsi = new MockBatteryStatsImpl();
         TestServ serv = new TestServ(bsi);
 
         serv.populate();
@@ -335,11 +310,6 @@
     public void testStartRunningLockedWhileRunning() throws Exception  {
         MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() {
             @Override
-            public long getBatteryUptimeLocked() {
-                return 777777L * 1000; // microseconds
-            }
-
-            @Override
             public long getBatteryUptimeLocked(long uptimeMs) {
                 return 777777L * 1000; // microseconds
             }
@@ -369,11 +339,6 @@
     public void testStartRunningLockedWhileNotRunning() throws Exception  {
         MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() {
             @Override
-            public long getBatteryUptimeLocked() {
-                return 777777L * 1000; // microseconds
-            }
-
-            @Override
             public long getBatteryUptimeLocked(long uptimeMs) {
                 return 777777L * 1000; // microseconds
             }
@@ -403,11 +368,6 @@
     public void testStopRunningLockedWhileRunningNormal() throws Exception  {
         MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() {
             @Override
-            public long getBatteryUptimeLocked() {
-                return 777777L * 1000; // microseconds
-            }
-
-            @Override
             public long getBatteryUptimeLocked(long uptimeMs) {
                 return 777777L * 1000; // microseconds
             }
@@ -435,12 +395,7 @@
      */
     @SmallTest
     public void testStopRunningLockedWhileRunningTooQuick() throws Exception  {
-        MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() {
-            @Override
-            public long getBatteryUptimeLocked() {
-                return 2021;
-            }
-        };
+        MockBatteryStatsImpl bsi = new MockBatteryStatsImpl();
         TestServ serv = new TestServ(bsi);
 
         serv.populate();
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/MockBatteryStatsImpl.java b/services/tests/servicestests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
index 3d015c0..713e786 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
+++ b/services/tests/servicestests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
@@ -240,11 +240,6 @@
         }
 
         @Override
-        public Future<?> scheduleCpuSyncDueToSettingChange() {
-            return null;
-        }
-
-        @Override
         public Future<?> scheduleSyncDueToScreenStateChange(int flag, boolean onBattery,
                 boolean onBatteryScreenOff, int screenState, int[] perDisplayScreenStates) {
             flags |= flag;
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/ConfigurationInternalTest.java b/services/tests/servicestests/src/com/android/server/timedetector/ConfigurationInternalTest.java
index c3d40da..208f99a 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/ConfigurationInternalTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/ConfigurationInternalTest.java
@@ -45,7 +45,9 @@
 
     private static final int ARBITRARY_USER_ID = 99999;
     private static final int ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS = 1234;
-    private static final Instant ARBITRARY_AUTO_TIME_LOWER_BOUND = Instant.ofEpochMilli(0);
+    private static final Instant ARBITRARY_SUGGESTION_LOWER_BOUND = Instant.ofEpochMilli(0);
+    private static final Instant ARBITRARY_SUGGESTION_UPPER_BOUND =
+            Instant.ofEpochMilli(Long.MAX_VALUE);
     private static final @Origin int[] ARBITRARY_ORIGIN_PRIORITIES = { ORIGIN_NETWORK };
 
     /**
@@ -59,9 +61,10 @@
                 .setUserConfigAllowed(true)
                 .setAutoDetectionSupported(true)
                 .setSystemClockUpdateThresholdMillis(ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS)
-                .setAutoTimeLowerBound(ARBITRARY_AUTO_TIME_LOWER_BOUND)
+                .setAutoSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
+                .setManualSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
+                .setSuggestionUpperBound(ARBITRARY_SUGGESTION_UPPER_BOUND)
                 .setOriginPriorities(ARBITRARY_ORIGIN_PRIORITIES)
-                .setDeviceHasY2038Issue(true)
                 .setAutoDetectionEnabledSetting(true)
                 .build();
         {
@@ -110,9 +113,10 @@
                 .setUserConfigAllowed(false)
                 .setAutoDetectionSupported(true)
                 .setSystemClockUpdateThresholdMillis(ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS)
-                .setAutoTimeLowerBound(ARBITRARY_AUTO_TIME_LOWER_BOUND)
+                .setAutoSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
+                .setManualSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
+                .setSuggestionUpperBound(ARBITRARY_SUGGESTION_UPPER_BOUND)
                 .setOriginPriorities(ARBITRARY_ORIGIN_PRIORITIES)
-                .setDeviceHasY2038Issue(true)
                 .setAutoDetectionEnabledSetting(true)
                 .build();
         {
@@ -159,9 +163,10 @@
                 .setUserConfigAllowed(true)
                 .setAutoDetectionSupported(false)
                 .setSystemClockUpdateThresholdMillis(ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS)
-                .setAutoTimeLowerBound(ARBITRARY_AUTO_TIME_LOWER_BOUND)
+                .setAutoSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
+                .setManualSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
+                .setSuggestionUpperBound(ARBITRARY_SUGGESTION_UPPER_BOUND)
                 .setOriginPriorities(ARBITRARY_ORIGIN_PRIORITIES)
-                .setDeviceHasY2038Issue(true)
                 .setAutoDetectionEnabledSetting(true)
                 .build();
         {
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java b/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java
new file mode 100644
index 0000000..1c6add2
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.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 com.android.server.timedetector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.annotation.UserIdInt;
+import android.app.time.ExternalTimeSuggestion;
+import android.app.timedetector.ManualTimeSuggestion;
+import android.app.timedetector.TelephonyTimeSuggestion;
+import android.util.IndentingPrintWriter;
+
+/**
+ * A fake implementation of {@link com.android.server.timedetector.TimeDetectorStrategy} for use
+ * in tests.
+ */
+class FakeTimeDetectorStrategy implements TimeDetectorStrategy {
+
+    // Call tracking.
+    private TelephonyTimeSuggestion mLastTelephonySuggestion;
+    private @UserIdInt Integer mLastManualSuggestionUserId;
+    private ManualTimeSuggestion mLastManualSuggestion;
+    private NetworkTimeSuggestion mLastNetworkSuggestion;
+    private GnssTimeSuggestion mLastGnssSuggestion;
+    private ExternalTimeSuggestion mLastExternalSuggestion;
+    private boolean mDumpCalled;
+
+    @Override
+    public void suggestTelephonyTime(TelephonyTimeSuggestion timeSuggestion) {
+        mLastTelephonySuggestion = timeSuggestion;
+    }
+
+    @Override
+    public boolean suggestManualTime(@UserIdInt int userId, ManualTimeSuggestion timeSuggestion) {
+        mLastManualSuggestionUserId = userId;
+        mLastManualSuggestion = timeSuggestion;
+        return true;
+    }
+
+    @Override
+    public void suggestNetworkTime(NetworkTimeSuggestion timeSuggestion) {
+        mLastNetworkSuggestion = timeSuggestion;
+    }
+
+    @Override
+    public void suggestGnssTime(GnssTimeSuggestion timeSuggestion) {
+        mLastGnssSuggestion = timeSuggestion;
+    }
+
+    @Override
+    public void suggestExternalTime(ExternalTimeSuggestion timeSuggestion) {
+        mLastExternalSuggestion = timeSuggestion;
+    }
+
+    @Override
+    public void dump(IndentingPrintWriter pw, String[] args) {
+        mDumpCalled = true;
+    }
+
+    void resetCallTracking() {
+        mLastTelephonySuggestion = null;
+        mLastManualSuggestionUserId = null;
+        mLastManualSuggestion = null;
+        mLastNetworkSuggestion = null;
+        mLastGnssSuggestion = null;
+        mLastExternalSuggestion = null;
+        mDumpCalled = false;
+    }
+
+    void verifySuggestTelephonyTimeCalled(TelephonyTimeSuggestion expectedSuggestion) {
+        assertEquals(expectedSuggestion, mLastTelephonySuggestion);
+    }
+
+    void verifySuggestManualTimeCalled(
+            @UserIdInt int expectedUserId, ManualTimeSuggestion expectedSuggestion) {
+        assertEquals((Integer) expectedUserId, mLastManualSuggestionUserId);
+        assertEquals(expectedSuggestion, mLastManualSuggestion);
+    }
+
+    void verifySuggestNetworkTimeCalled(NetworkTimeSuggestion expectedSuggestion) {
+        assertEquals(expectedSuggestion, mLastNetworkSuggestion);
+    }
+
+    void verifySuggestGnssTimeCalled(GnssTimeSuggestion expectedSuggestion) {
+        assertEquals(expectedSuggestion, mLastGnssSuggestion);
+    }
+
+    void verifySuggestExternalTimeCalled(ExternalTimeSuggestion expectedSuggestion) {
+        assertEquals(expectedSuggestion, mLastExternalSuggestion);
+    }
+
+    void verifyDumpCalled() {
+        assertTrue(mDumpCalled);
+    }
+}
diff --git a/core/tests/coretests/src/android/app/timedetector/GnssTimeSuggestionTest.java b/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeSuggestionTest.java
similarity index 80%
rename from core/tests/coretests/src/android/app/timedetector/GnssTimeSuggestionTest.java
rename to services/tests/servicestests/src/com/android/server/timedetector/GnssTimeSuggestionTest.java
index af403a2..f25d94e 100644
--- a/core/tests/coretests/src/android/app/timedetector/GnssTimeSuggestionTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeSuggestionTest.java
@@ -14,11 +14,9 @@
  * limitations under the License.
  */
 
-package android.app.timedetector;
+package com.android.server.timedetector;
 
-import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
-import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
-import static android.app.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;
+import static com.android.server.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
@@ -55,17 +53,6 @@
         assertEquals(one, two);
     }
 
-    @Test
-    public void testParcelable() {
-        GnssTimeSuggestion suggestion = new GnssTimeSuggestion(ARBITRARY_TIME);
-        assertRoundTripParcelable(suggestion);
-
-        // DebugInfo should also be stored (but is not checked by equals()
-        suggestion.addDebugInfo("This is debug info");
-        GnssTimeSuggestion rtSuggestion = roundTripParcelable(suggestion);
-        assertEquals(suggestion.getDebugInfo(), rtSuggestion.getDebugInfo());
-    }
-
     @Test(expected = IllegalArgumentException.class)
     public void testParseCommandLineArg_noReferenceTime() {
         ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java
index aad5cd6..6402e12 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java
@@ -19,15 +19,12 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyLong;
-import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.AlarmManager;
-import android.app.timedetector.GnssTimeSuggestion;
-import android.app.timedetector.TimeDetector;
 import android.content.Context;
 import android.location.Location;
 import android.location.LocationListener;
@@ -56,10 +53,10 @@
     private static final long ELAPSED_REALTIME_MS = ELAPSED_REALTIME_NS / 1_000_000L;
 
     @Mock private Context mMockContext;
-    @Mock private TimeDetector mMockTimeDetector;
     @Mock private AlarmManager mMockAlarmManager;
     @Mock private LocationManager mMockLocationManager;
-    @Mock private LocationManagerInternal mLocationManagerInternal;
+    @Mock private LocationManagerInternal mMockLocationManagerInternal;
+    @Mock private TimeDetectorInternal mMockTimeDetectorInternal;
 
     private GnssTimeUpdateService mGnssTimeUpdateService;
 
@@ -67,31 +64,12 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        when(mMockContext.createAttributionContext(anyString()))
-                .thenReturn(mMockContext);
-
-        when(mMockContext.getSystemServiceName(TimeDetector.class))
-                .thenReturn((TimeDetector.class).getSimpleName());
-        when(mMockContext.getSystemService(TimeDetector.class))
-                .thenReturn(mMockTimeDetector);
-
-        when(mMockContext.getSystemServiceName(LocationManager.class))
-                .thenReturn((LocationManager.class).getSimpleName());
-        when(mMockContext.getSystemService(LocationManager.class))
-                .thenReturn(mMockLocationManager);
-
-        when(mMockContext.getSystemServiceName(AlarmManager.class))
-                .thenReturn((AlarmManager.class).getSimpleName());
-        when(mMockContext.getSystemService(AlarmManager.class))
-                .thenReturn(mMockAlarmManager);
-
         when(mMockLocationManager.hasProvider(LocationManager.GPS_PROVIDER))
                 .thenReturn(true);
 
-        LocalServices.addService(LocationManagerInternal.class, mLocationManagerInternal);
-
-        mGnssTimeUpdateService =
-                new GnssTimeUpdateService(mMockContext);
+        mGnssTimeUpdateService = new GnssTimeUpdateService(
+                mMockContext, mMockAlarmManager, mMockLocationManager, mMockLocationManagerInternal,
+                mMockTimeDetectorInternal);
     }
 
     @After
@@ -105,7 +83,7 @@
                 ELAPSED_REALTIME_MS, GNSS_TIME);
         GnssTimeSuggestion timeSuggestion = new GnssTimeSuggestion(timeSignal);
         LocationTime locationTime = new LocationTime(GNSS_TIME, ELAPSED_REALTIME_NS);
-        doReturn(locationTime).when(mLocationManagerInternal).getGnssTimeMillis();
+        doReturn(locationTime).when(mMockLocationManagerInternal).getGnssTimeMillis();
 
         mGnssTimeUpdateService.requestGnssTimeUpdates();
 
@@ -124,7 +102,7 @@
         locationListener.onLocationChanged(location);
 
         verify(mMockLocationManager).removeUpdates(locationListener);
-        verify(mMockTimeDetector).suggestGnssTime(timeSuggestion);
+        verify(mMockTimeDetectorInternal).suggestGnssTime(timeSuggestion);
         verify(mMockAlarmManager).set(
                 eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
                 anyLong(),
@@ -135,7 +113,7 @@
 
     @Test
     public void testLocationListenerOnLocationChanged_nullLocationTime_doesNotSuggestGnssTime() {
-        doReturn(null).when(mLocationManagerInternal).getGnssTimeMillis();
+        doReturn(null).when(mMockLocationManagerInternal).getGnssTimeMillis();
 
         mGnssTimeUpdateService.requestGnssTimeUpdates();
 
@@ -154,7 +132,7 @@
         locationListener.onLocationChanged(location);
 
         verify(mMockLocationManager).removeUpdates(locationListener);
-        verify(mMockTimeDetector, never()).suggestGnssTime(any());
+        verify(mMockTimeDetectorInternal, never()).suggestGnssTime(any());
         verify(mMockAlarmManager).set(
                 eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
                 anyLong(),
diff --git a/core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java b/services/tests/servicestests/src/com/android/server/timedetector/NetworkTimeSuggestionTest.java
similarity index 69%
rename from core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java
rename to services/tests/servicestests/src/com/android/server/timedetector/NetworkTimeSuggestionTest.java
index 0e09dd3..f5a37b9 100644
--- a/core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/NetworkTimeSuggestionTest.java
@@ -14,11 +14,9 @@
  * limitations under the License.
  */
 
-package android.app.timedetector;
+package com.android.server.timedetector;
 
-import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
-import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
-import static android.app.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;
+import static com.android.server.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
@@ -32,60 +30,66 @@
 
     private static final TimestampedValue<Long> ARBITRARY_TIME =
             new TimestampedValue<>(1111L, 2222L);
+    private static final int ARBITRARY_UNCERTAINTY_MILLIS = 3333;
 
     @Test
     public void testEquals() {
-        NetworkTimeSuggestion one = new NetworkTimeSuggestion(ARBITRARY_TIME);
+        NetworkTimeSuggestion one = new NetworkTimeSuggestion(
+                ARBITRARY_TIME, ARBITRARY_UNCERTAINTY_MILLIS);
         assertEquals(one, one);
 
-        NetworkTimeSuggestion two = new NetworkTimeSuggestion(ARBITRARY_TIME);
+        NetworkTimeSuggestion two =
+                new NetworkTimeSuggestion(ARBITRARY_TIME, ARBITRARY_UNCERTAINTY_MILLIS);
         assertEquals(one, two);
         assertEquals(two, one);
 
         TimestampedValue<Long> differentTime = new TimestampedValue<>(
                 ARBITRARY_TIME.getReferenceTimeMillis() + 1,
                 ARBITRARY_TIME.getValue());
-        NetworkTimeSuggestion three = new NetworkTimeSuggestion(differentTime);
+        NetworkTimeSuggestion three = new NetworkTimeSuggestion(
+                differentTime, ARBITRARY_UNCERTAINTY_MILLIS);
         assertNotEquals(one, three);
         assertNotEquals(three, one);
 
+        int differentUncertainty = ARBITRARY_UNCERTAINTY_MILLIS + 1;
+        NetworkTimeSuggestion four = new NetworkTimeSuggestion(
+                ARBITRARY_TIME, differentUncertainty);
+        assertNotEquals(one, four);
+        assertNotEquals(four, one);
+
         // DebugInfo must not be considered in equals().
         one.addDebugInfo("Debug info 1");
         two.addDebugInfo("Debug info 2");
         assertEquals(one, two);
     }
 
-    @Test
-    public void testParcelable() {
-        NetworkTimeSuggestion suggestion = new NetworkTimeSuggestion(ARBITRARY_TIME);
-        assertRoundTripParcelable(suggestion);
-
-        // DebugInfo should also be stored (but is not checked by equals()
-        suggestion.addDebugInfo("This is debug info");
-        NetworkTimeSuggestion rtSuggestion = roundTripParcelable(suggestion);
-        assertEquals(suggestion.getDebugInfo(), rtSuggestion.getDebugInfo());
-    }
-
     @Test(expected = IllegalArgumentException.class)
     public void testParseCommandLineArg_noReferenceTime() {
         ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
-                "--unix_epoch_time 12345");
+                "--unix_epoch_time 12345 --uncertainty_millis 111");
         NetworkTimeSuggestion.parseCommandLineArg(testShellCommand);
     }
 
     @Test(expected = IllegalArgumentException.class)
     public void testParseCommandLineArg_noUnixEpochTime() {
         ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
-                "--reference_time 54321");
+                "--reference_time 54321 --uncertainty_millis 111");
+        NetworkTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_noUncertaintyMillis() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--reference_time 54321 --unix_epoch_time 12345");
         NetworkTimeSuggestion.parseCommandLineArg(testShellCommand);
     }
 
     @Test
     public void testParseCommandLineArg_validSuggestion() {
         ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
-                "--reference_time 54321 --unix_epoch_time 12345");
+                "--reference_time 54321 --unix_epoch_time 12345 --uncertainty_millis 111");
         TimestampedValue<Long> timeSignal = new TimestampedValue<>(54321L, 12345L);
-        NetworkTimeSuggestion expectedSuggestion = new NetworkTimeSuggestion(timeSignal);
+        NetworkTimeSuggestion expectedSuggestion = new NetworkTimeSuggestion(timeSignal, 111);
         NetworkTimeSuggestion actualSuggestion =
                 NetworkTimeSuggestion.parseCommandLineArg(testShellCommand);
         assertEquals(expectedSuggestion, actualSuggestion);
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java
new file mode 100644
index 0000000..f8092a6
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.timedetector;
+
+import static org.mockito.Mockito.mock;
+
+import android.content.Context;
+import android.os.HandlerThread;
+import android.os.TimestampedValue;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.timezonedetector.TestHandler;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class TimeDetectorInternalImplTest {
+
+    private Context mMockContext;
+    private FakeTimeDetectorStrategy mFakeTimeDetectorStrategy;
+
+    private TimeDetectorInternalImpl mTimeDetectorInternal;
+    private HandlerThread mHandlerThread;
+    private TestHandler mTestHandler;
+
+    @Before
+    public void setUp() {
+        mMockContext = mock(Context.class);
+
+        // Create a thread + handler for processing the work that the service posts.
+        mHandlerThread = new HandlerThread("TimeDetectorInternalTest");
+        mHandlerThread.start();
+        mTestHandler = new TestHandler(mHandlerThread.getLooper());
+
+        mFakeTimeDetectorStrategy = new FakeTimeDetectorStrategy();
+
+        mTimeDetectorInternal = new TimeDetectorInternalImpl(
+                mMockContext, mTestHandler, mFakeTimeDetectorStrategy);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mHandlerThread.quit();
+        mHandlerThread.join();
+    }
+
+    @Test
+    public void testSuggestNetworkTime() throws Exception {
+        NetworkTimeSuggestion networkTimeSuggestion = createNetworkTimeSuggestion();
+
+        mTimeDetectorInternal.suggestNetworkTime(networkTimeSuggestion);
+        mTestHandler.assertTotalMessagesEnqueued(1);
+
+        mTestHandler.waitForMessagesToBeProcessed();
+        mFakeTimeDetectorStrategy.verifySuggestNetworkTimeCalled(networkTimeSuggestion);
+    }
+
+    private static NetworkTimeSuggestion createNetworkTimeSuggestion() {
+        TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L);
+        return new NetworkTimeSuggestion(timeValue, 123);
+    }
+
+    @Test
+    public void testSuggestGnssTime() throws Exception {
+        GnssTimeSuggestion gnssTimeSuggestion = createGnssTimeSuggestion();
+
+        mTimeDetectorInternal.suggestGnssTime(gnssTimeSuggestion);
+        mTestHandler.assertTotalMessagesEnqueued(1);
+
+        mTestHandler.waitForMessagesToBeProcessed();
+        mFakeTimeDetectorStrategy.verifySuggestGnssTimeCalled(gnssTimeSuggestion);
+    }
+
+    private static GnssTimeSuggestion createGnssTimeSuggestion() {
+        TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L);
+        return new GnssTimeSuggestion(timeValue);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
index e9617e9..67c8c4f 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
@@ -19,6 +19,7 @@
 import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_NETWORK;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
@@ -37,16 +38,16 @@
 import android.app.time.ExternalTimeSuggestion;
 import android.app.time.ITimeDetectorListener;
 import android.app.time.TimeConfiguration;
-import android.app.timedetector.GnssTimeSuggestion;
 import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timedetector.NetworkTimeSuggestion;
 import android.app.timedetector.TelephonyTimeSuggestion;
+import android.app.timedetector.TimePoint;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.HandlerThread;
 import android.os.IBinder;
+import android.os.ParcelableException;
 import android.os.TimestampedValue;
-import android.util.IndentingPrintWriter;
+import android.util.NtpTrustedTime;
 
 import androidx.test.runner.AndroidJUnit4;
 
@@ -60,6 +61,7 @@
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.net.InetSocketAddress;
 import java.time.Instant;
 
 @RunWith(AndroidJUnit4.class)
@@ -67,7 +69,9 @@
 
     private static final int ARBITRARY_USER_ID = 9999;
     private static final int ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS = 1234;
-    private static final Instant ARBITRARY_AUTO_TIME_LOWER_BOUND = Instant.ofEpochMilli(0);
+    private static final Instant ARBITRARY_SUGGESTION_LOWER_BOUND = Instant.ofEpochMilli(0);
+    private static final Instant ARBITRARY_SUGGESTION_UPPER_BOUND =
+            Instant.ofEpochMilli(Long.MAX_VALUE);
     private static final int[] ARBITRARY_ORIGIN_PRIORITIES = { ORIGIN_NETWORK };
 
     private Context mMockContext;
@@ -77,7 +81,8 @@
     private TestHandler mTestHandler;
     private TestCallerIdentityInjector mTestCallerIdentityInjector;
     private FakeServiceConfigAccessor mFakeServiceConfigAccessor;
-    private StubbedTimeDetectorStrategy mStubbedTimeDetectorStrategy;
+    private NtpTrustedTime mMockNtpTrustedTime;
+    private FakeTimeDetectorStrategy mFakeTimeDetectorStrategy;
 
 
     @Before
@@ -92,12 +97,13 @@
         mTestCallerIdentityInjector = new TestCallerIdentityInjector();
         mTestCallerIdentityInjector.initializeCallingUserId(ARBITRARY_USER_ID);
 
-        mStubbedTimeDetectorStrategy = new StubbedTimeDetectorStrategy();
+        mFakeTimeDetectorStrategy = new FakeTimeDetectorStrategy();
         mFakeServiceConfigAccessor = new FakeServiceConfigAccessor();
+        mMockNtpTrustedTime = mock(NtpTrustedTime.class);
 
         mTimeDetectorService = new TimeDetectorService(
                 mMockContext, mTestHandler, mFakeServiceConfigAccessor,
-                mStubbedTimeDetectorStrategy, mTestCallerIdentityInjector);
+                mFakeTimeDetectorStrategy, mTestCallerIdentityInjector, mMockNtpTrustedTime);
     }
 
     @After
@@ -275,7 +281,7 @@
                 anyString());
 
         mTestHandler.waitForMessagesToBeProcessed();
-        mStubbedTimeDetectorStrategy.verifySuggestTelephonyTimeCalled(timeSuggestion);
+        mFakeTimeDetectorStrategy.verifySuggestTelephonyTimeCalled(timeSuggestion);
     }
 
     @Test(expected = SecurityException.class)
@@ -301,7 +307,8 @@
         ManualTimeSuggestion manualTimeSuggestion = createManualTimeSuggestion();
 
         assertTrue(mTimeDetectorService.suggestManualTime(manualTimeSuggestion));
-        mStubbedTimeDetectorStrategy.verifySuggestManualTimeCalled(manualTimeSuggestion);
+        mFakeTimeDetectorStrategy.verifySuggestManualTimeCalled(
+                mTestCallerIdentityInjector.getCallingUserId(), manualTimeSuggestion);
 
         verify(mMockContext).enforceCallingOrSelfPermission(
                 eq(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE),
@@ -313,10 +320,10 @@
     public void testSuggestNetworkTime_withoutPermission() {
         doThrow(new SecurityException("Mock"))
                 .when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
-        NetworkTimeSuggestion NetworkTimeSuggestion = createNetworkTimeSuggestion();
+        NetworkTimeSuggestion networkTimeSuggestion = createNetworkTimeSuggestion();
 
         try {
-            mTimeDetectorService.suggestNetworkTime(NetworkTimeSuggestion);
+            mTimeDetectorService.suggestNetworkTime(networkTimeSuggestion);
             fail();
         } finally {
             verify(mMockContext).enforceCallingOrSelfPermission(
@@ -328,15 +335,15 @@
     public void testSuggestNetworkTime() throws Exception {
         doNothing().when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
 
-        NetworkTimeSuggestion NetworkTimeSuggestion = createNetworkTimeSuggestion();
-        mTimeDetectorService.suggestNetworkTime(NetworkTimeSuggestion);
+        NetworkTimeSuggestion networkTimeSuggestion = createNetworkTimeSuggestion();
+        mTimeDetectorService.suggestNetworkTime(networkTimeSuggestion);
         mTestHandler.assertTotalMessagesEnqueued(1);
 
         verify(mMockContext).enforceCallingOrSelfPermission(
                 eq(android.Manifest.permission.SET_TIME), anyString());
 
         mTestHandler.waitForMessagesToBeProcessed();
-        mStubbedTimeDetectorStrategy.verifySuggestNetworkTimeCalled(NetworkTimeSuggestion);
+        mFakeTimeDetectorStrategy.verifySuggestNetworkTimeCalled(networkTimeSuggestion);
     }
 
     @Test(expected = SecurityException.class)
@@ -366,7 +373,7 @@
                 eq(android.Manifest.permission.SET_TIME), anyString());
 
         mTestHandler.waitForMessagesToBeProcessed();
-        mStubbedTimeDetectorStrategy.verifySuggestGnssTimeCalled(gnssTimeSuggestion);
+        mFakeTimeDetectorStrategy.verifySuggestGnssTimeCalled(gnssTimeSuggestion);
     }
 
     @Test(expected = SecurityException.class)
@@ -396,7 +403,24 @@
                 eq(android.Manifest.permission.SUGGEST_EXTERNAL_TIME), anyString());
 
         mTestHandler.waitForMessagesToBeProcessed();
-        mStubbedTimeDetectorStrategy.verifySuggestExternalTimeCalled(externalTimeSuggestion);
+        mFakeTimeDetectorStrategy.verifySuggestExternalTimeCalled(externalTimeSuggestion);
+    }
+
+    @Test
+    public void testLatestNetworkTime() {
+        NtpTrustedTime.TimeResult latestNetworkTime = new NtpTrustedTime.TimeResult(
+                1234L, 54321L, 999, InetSocketAddress.createUnresolved("test.timeserver", 123));
+        when(mMockNtpTrustedTime.getCachedTimeResult())
+                .thenReturn(latestNetworkTime);
+        TimePoint expected = new TimePoint(latestNetworkTime.getTimeMillis(),
+                latestNetworkTime.getElapsedRealtimeMillis());
+        assertEquals(expected, mTimeDetectorService.latestNetworkTime());
+    }
+
+    @Test
+    public void testLatestNetworkTime_noTimeAvailable() {
+        when(mMockNtpTrustedTime.getCachedTimeResult()).thenReturn(null);
+        assertThrows(ParcelableException.class, () -> mTimeDetectorService.latestNetworkTime());
     }
 
     @Test
@@ -408,7 +432,7 @@
         mTimeDetectorService.dump(null, pw, null);
 
         verify(mMockContext).checkCallingOrSelfPermission(eq(android.Manifest.permission.DUMP));
-        mStubbedTimeDetectorStrategy.verifyDumpCalled();
+        mFakeTimeDetectorStrategy.verifyDumpCalled();
     }
 
     private static TimeConfiguration createTimeConfiguration(boolean autoDetectionEnabled) {
@@ -422,9 +446,10 @@
                 .setUserConfigAllowed(true)
                 .setAutoDetectionSupported(true)
                 .setSystemClockUpdateThresholdMillis(ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS)
-                .setAutoTimeLowerBound(ARBITRARY_AUTO_TIME_LOWER_BOUND)
+                .setAutoSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
+                .setManualSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
+                .setSuggestionUpperBound(ARBITRARY_SUGGESTION_UPPER_BOUND)
                 .setOriginPriorities(ARBITRARY_ORIGIN_PRIORITIES)
-                .setDeviceHasY2038Issue(true)
                 .setAutoDetectionEnabledSetting(autoDetectionEnabled)
                 .build();
     }
@@ -444,7 +469,7 @@
 
     private static NetworkTimeSuggestion createNetworkTimeSuggestion() {
         TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L);
-        return new NetworkTimeSuggestion(timeValue);
+        return new NetworkTimeSuggestion(timeValue, 123);
     }
 
     private static GnssTimeSuggestion createGnssTimeSuggestion() {
@@ -455,79 +480,4 @@
     private static ExternalTimeSuggestion createExternalTimeSuggestion() {
         return new ExternalTimeSuggestion(100L, 1_000_000L);
     }
-
-    private static class StubbedTimeDetectorStrategy implements TimeDetectorStrategy {
-
-        // Call tracking.
-        private TelephonyTimeSuggestion mLastTelephonySuggestion;
-        private ManualTimeSuggestion mLastManualSuggestion;
-        private NetworkTimeSuggestion mLastNetworkSuggestion;
-        private GnssTimeSuggestion mLastGnssSuggestion;
-        private ExternalTimeSuggestion mLastExternalSuggestion;
-        private boolean mDumpCalled;
-
-        @Override
-        public void suggestTelephonyTime(TelephonyTimeSuggestion timeSuggestion) {
-            mLastTelephonySuggestion = timeSuggestion;
-        }
-
-        @Override
-        public boolean suggestManualTime(int userId, ManualTimeSuggestion timeSuggestion) {
-            mLastManualSuggestion = timeSuggestion;
-            return true;
-        }
-
-        @Override
-        public void suggestNetworkTime(NetworkTimeSuggestion timeSuggestion) {
-            mLastNetworkSuggestion = timeSuggestion;
-        }
-
-        @Override
-        public void suggestGnssTime(GnssTimeSuggestion timeSuggestion) {
-            mLastGnssSuggestion = timeSuggestion;
-        }
-
-        @Override
-        public void suggestExternalTime(ExternalTimeSuggestion timeSuggestion) {
-            mLastExternalSuggestion = timeSuggestion;
-        }
-
-        @Override
-        public void dump(IndentingPrintWriter pw, String[] args) {
-            mDumpCalled = true;
-        }
-
-        void resetCallTracking() {
-            mLastTelephonySuggestion = null;
-            mLastManualSuggestion = null;
-            mLastNetworkSuggestion = null;
-            mLastGnssSuggestion = null;
-            mLastExternalSuggestion = null;
-            mDumpCalled = false;
-        }
-
-        void verifySuggestTelephonyTimeCalled(TelephonyTimeSuggestion expectedSuggestion) {
-            assertEquals(expectedSuggestion, mLastTelephonySuggestion);
-        }
-
-        void verifySuggestManualTimeCalled(ManualTimeSuggestion expectedSuggestion) {
-            assertEquals(expectedSuggestion, mLastManualSuggestion);
-        }
-
-        void verifySuggestNetworkTimeCalled(NetworkTimeSuggestion expectedSuggestion) {
-            assertEquals(expectedSuggestion, mLastNetworkSuggestion);
-        }
-
-        void verifySuggestGnssTimeCalled(GnssTimeSuggestion expectedSuggestion) {
-            assertEquals(expectedSuggestion, mLastGnssSuggestion);
-        }
-
-        void verifySuggestExternalTimeCalled(ExternalTimeSuggestion expectedSuggestion) {
-            assertEquals(expectedSuggestion, mLastExternalSuggestion);
-        }
-
-        void verifyDumpCalled() {
-            assertTrue(mDumpCalled);
-        }
-    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
index 15a8996..1aea672 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
@@ -29,9 +29,7 @@
 
 import android.annotation.UserIdInt;
 import android.app.time.ExternalTimeSuggestion;
-import android.app.timedetector.GnssTimeSuggestion;
 import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timedetector.NetworkTimeSuggestion;
 import android.app.timedetector.TelephonyTimeSuggestion;
 import android.os.TimestampedValue;
 
@@ -55,7 +53,16 @@
 
     private static final @UserIdInt int ARBITRARY_USER_ID = 9876;
     private static final int ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS = 1234;
-    private static final Instant TIME_LOWER_BOUND = createUnixEpochTime(2009, 1, 1, 12, 0, 0);
+    private static final Instant DEFAULT_SUGGESTION_LOWER_BOUND =
+            createUnixEpochTime(2005, 1, 1, 1, 0, 0);
+    /** A value after {@link #DEFAULT_SUGGESTION_LOWER_BOUND} */
+    private static final Instant TEST_SUGGESTION_LOWER_BOUND =
+            createUnixEpochTime(2006, 1, 1, 1, 0, 0);
+    private static final Instant DEFAULT_SUGGESTION_UPPER_BOUND =
+            createUnixEpochTime(2099, 12, 1, 1, 0, 0);
+    /** A value before {@link #DEFAULT_SUGGESTION_UPPER_BOUND} */
+    private static final Instant TEST_SUGGESTION_UPPER_BOUND =
+            createUnixEpochTime(2037, 12, 1, 1, 0, 0);
 
     private static final TimestampedValue<Instant> ARBITRARY_CLOCK_INITIALIZATION_INFO =
             new TimestampedValue<>(
@@ -79,9 +86,10 @@
                     .setAutoDetectionSupported(true)
                     .setSystemClockUpdateThresholdMillis(
                             ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS)
-                    .setAutoTimeLowerBound(TIME_LOWER_BOUND)
+                    .setAutoSuggestionLowerBound(DEFAULT_SUGGESTION_LOWER_BOUND)
+                    .setManualSuggestionLowerBound(DEFAULT_SUGGESTION_LOWER_BOUND)
+                    .setSuggestionUpperBound(DEFAULT_SUGGESTION_UPPER_BOUND)
                     .setOriginPriorities(ORIGIN_PRIORITIES)
-                    .setDeviceHasY2038Issue(true)
                     .setAutoDetectionEnabledSetting(false)
                     .build();
 
@@ -91,9 +99,10 @@
                     .setAutoDetectionSupported(true)
                     .setSystemClockUpdateThresholdMillis(
                             ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS)
-                    .setAutoTimeLowerBound(TIME_LOWER_BOUND)
+                    .setAutoSuggestionLowerBound(DEFAULT_SUGGESTION_LOWER_BOUND)
+                    .setManualSuggestionLowerBound(DEFAULT_SUGGESTION_LOWER_BOUND)
+                    .setSuggestionUpperBound(DEFAULT_SUGGESTION_UPPER_BOUND)
                     .setOriginPriorities(ORIGIN_PRIORITIES)
-                    .setDeviceHasY2038Issue(true)
                     .setAutoDetectionEnabledSetting(true)
                     .build();
 
@@ -346,22 +355,6 @@
     }
 
     @Test
-    public void telephonyTimeSuggestion_ignoredWhenReferencedTimeIsInThePast() {
-        Script script = new Script().simulateConfigurationInternalChange(CONFIG_AUTO_ENABLED);
-
-        int slotIndex = ARBITRARY_SLOT_INDEX;
-        Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1));
-
-        TelephonyTimeSuggestion timeSuggestion =
-                script.generateTelephonyTimeSuggestion(
-                        slotIndex, suggestedTime);
-
-        script.simulateTelephonyTimeSuggestion(timeSuggestion)
-                .verifySystemClockWasNotSetAndResetCallTracking()
-                .assertLatestTelephonySuggestion(slotIndex, null);
-    }
-
-    @Test
     public void testSuggestTelephonyTime_timeDetectionToggled() {
         final int clockIncrementMillis = 100;
         final int systemClockUpdateThresholdMillis = 2000;
@@ -455,6 +448,70 @@
     }
 
     @Test
+    public void testSuggestTelephonyTime_rejectedBelowLowerBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_DISABLED)
+                        .setOriginPriorities(ORIGIN_TELEPHONY)
+                        .setAutoSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant belowLowerBound = TEST_SUGGESTION_LOWER_BOUND.minusSeconds(1);
+        TelephonyTimeSuggestion timeSuggestion =
+                script.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, belowLowerBound);
+        script.simulateTelephonyTimeSuggestion(timeSuggestion)
+                .verifySystemClockWasNotSetAndResetCallTracking();
+    }
+
+    @Test
+    public void testSuggestTelephonyTime_notRejectedAboveLowerBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
+                        .setOriginPriorities(ORIGIN_TELEPHONY)
+                        .setAutoSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant aboveLowerBound = TEST_SUGGESTION_LOWER_BOUND.plusSeconds(1);
+        TelephonyTimeSuggestion timeSuggestion =
+                script.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, aboveLowerBound);
+        script.simulateTelephonyTimeSuggestion(timeSuggestion)
+                .verifySystemClockWasSetAndResetCallTracking(aboveLowerBound.toEpochMilli());
+    }
+
+    @Test
+    public void testSuggestTelephonyTime_rejectedAboveUpperBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
+                        .setOriginPriorities(ORIGIN_TELEPHONY)
+                        .setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant aboveUpperBound = TEST_SUGGESTION_UPPER_BOUND.plusSeconds(1);
+        TelephonyTimeSuggestion timeSuggestion =
+                script.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, aboveUpperBound);
+        script.simulateTelephonyTimeSuggestion(timeSuggestion)
+                .verifySystemClockWasNotSetAndResetCallTracking();
+    }
+
+    @Test
+    public void testSuggestTelephonyTime_notRejectedBelowUpperBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
+                        .setOriginPriorities(ORIGIN_TELEPHONY)
+                        .setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant belowUpperBound = TEST_SUGGESTION_UPPER_BOUND.minusSeconds(1);
+        TelephonyTimeSuggestion timeSuggestion =
+                script.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, belowUpperBound);
+        script.simulateTelephonyTimeSuggestion(timeSuggestion)
+                .verifySystemClockWasSetAndResetCallTracking(belowUpperBound.toEpochMilli());
+    }
+
+    @Test
     public void testSuggestManualTime_autoTimeDisabled() {
         Script script = new Script().simulateConfigurationInternalChange(CONFIG_AUTO_DISABLED);
 
@@ -532,7 +589,7 @@
     }
 
     @Test
-    public void manualTimeSuggestion_isIgnored_whenAutoTimeEnabled() {
+    public void testSuggestManualTime_isIgnored_whenAutoTimeEnabled() {
         Script script = new Script().simulateConfigurationInternalChange(CONFIG_AUTO_ENABLED);
 
         ManualTimeSuggestion timeSuggestion =
@@ -545,16 +602,63 @@
     }
 
     @Test
-    public void manualTimeSuggestion_ignoresTimeLowerBound() {
-        Script script = new Script().simulateConfigurationInternalChange(CONFIG_AUTO_DISABLED);
-        Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1));
+    public void testSuggestManualTime_rejectedAboveUpperBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_DISABLED)
+                        .setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
 
-        ManualTimeSuggestion timeSuggestion =
-                script.generateManualTimeSuggestion(suggestedTime);
-
+        Instant aboveUpperBound = TEST_SUGGESTION_UPPER_BOUND.plusSeconds(1);
+        ManualTimeSuggestion timeSuggestion = script.generateManualTimeSuggestion(aboveUpperBound);
         script.simulateManualTimeSuggestion(
-                ARBITRARY_USER_ID, timeSuggestion, true /* expectedResult */)
-                .verifySystemClockWasSetAndResetCallTracking(suggestedTime.toEpochMilli());
+                        ARBITRARY_USER_ID, timeSuggestion, false /* expectedResult */)
+                .verifySystemClockWasNotSetAndResetCallTracking();
+    }
+
+    @Test
+    public void testSuggestManualTime_notRejectedBelowUpperBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_DISABLED)
+                        .setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant belowUpperBound = TEST_SUGGESTION_UPPER_BOUND.minusSeconds(1);
+        ManualTimeSuggestion timeSuggestion = script.generateManualTimeSuggestion(belowUpperBound);
+        script.simulateManualTimeSuggestion(
+                        ARBITRARY_USER_ID, timeSuggestion, true /* expectedResult */)
+                .verifySystemClockWasSetAndResetCallTracking(belowUpperBound.toEpochMilli());
+    }
+
+    @Test
+    public void testSuggestManualTime_rejectedBelowLowerBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_DISABLED)
+                        .setManualSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant belowLowerBound = TEST_SUGGESTION_LOWER_BOUND.minusSeconds(1);
+        ManualTimeSuggestion timeSuggestion = script.generateManualTimeSuggestion(belowLowerBound);
+        script.simulateManualTimeSuggestion(
+                        ARBITRARY_USER_ID, timeSuggestion, false /* expectedResult */)
+                .verifySystemClockWasNotSetAndResetCallTracking();
+    }
+
+    @Test
+    public void testSuggestManualTimes_notRejectedAboveLowerBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_DISABLED)
+                        .setManualSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant aboveLowerBound = TEST_SUGGESTION_LOWER_BOUND.plusSeconds(1);
+        ManualTimeSuggestion timeSuggestion = script.generateManualTimeSuggestion(aboveLowerBound);
+        script.simulateManualTimeSuggestion(
+                        ARBITRARY_USER_ID, timeSuggestion, true /* expectedResult */)
+                .verifySystemClockWasSetAndResetCallTracking(aboveLowerBound.toEpochMilli());
     }
 
     @Test
@@ -593,20 +697,67 @@
     }
 
     @Test
-    public void networkTimeSuggestion_ignoredWhenReferencedTimeIsInThePast() {
+    public void testSuggestNetworkTime_rejectedBelowLowerBound() {
         ConfigurationInternal configInternal =
                 new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
                         .setOriginPriorities(ORIGIN_NETWORK)
+                        .setAutoSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
                         .build();
         Script script = new Script().simulateConfigurationInternalChange(configInternal);
 
-        Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1));
+        Instant belowLowerBound = TEST_SUGGESTION_LOWER_BOUND.minusSeconds(1);
         NetworkTimeSuggestion timeSuggestion =
-                script.generateNetworkTimeSuggestion(suggestedTime);
-
+                script.generateNetworkTimeSuggestion(belowLowerBound);
         script.simulateNetworkTimeSuggestion(timeSuggestion)
-                .verifySystemClockWasNotSetAndResetCallTracking()
-                .assertLatestNetworkSuggestion(null);
+                .verifySystemClockWasNotSetAndResetCallTracking();
+    }
+
+    @Test
+    public void testSuggestNetworkTime_notRejectedAboveLowerBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
+                        .setOriginPriorities(ORIGIN_NETWORK)
+                        .setAutoSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant aboveLowerBound = TEST_SUGGESTION_LOWER_BOUND.plusSeconds(1);
+        NetworkTimeSuggestion timeSuggestion =
+                script.generateNetworkTimeSuggestion(aboveLowerBound);
+        script.simulateNetworkTimeSuggestion(timeSuggestion)
+                .verifySystemClockWasSetAndResetCallTracking(aboveLowerBound.toEpochMilli());
+    }
+
+    @Test
+    public void testSuggestNetworkTime_rejectedAboveUpperBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
+                        .setOriginPriorities(ORIGIN_NETWORK)
+                        .setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant aboveUpperBound = TEST_SUGGESTION_UPPER_BOUND.plusSeconds(1);
+        NetworkTimeSuggestion timeSuggestion =
+                script.generateNetworkTimeSuggestion(aboveUpperBound);
+        script.simulateNetworkTimeSuggestion(timeSuggestion)
+                .verifySystemClockWasNotSetAndResetCallTracking();
+    }
+
+    @Test
+    public void testSuggestNetworkTime_notRejectedBelowUpperBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
+                        .setOriginPriorities(ORIGIN_NETWORK)
+                        .setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant belowUpperBound = TEST_SUGGESTION_UPPER_BOUND.minusSeconds(1);
+        NetworkTimeSuggestion timeSuggestion =
+                script.generateNetworkTimeSuggestion(belowUpperBound);
+        script.simulateNetworkTimeSuggestion(timeSuggestion)
+                .verifySystemClockWasSetAndResetCallTracking(belowUpperBound.toEpochMilli());
     }
 
     @Test
@@ -645,6 +796,70 @@
     }
 
     @Test
+    public void testSuggestGnssTime_rejectedBelowLowerBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
+                        .setOriginPriorities(ORIGIN_GNSS)
+                        .setAutoSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant belowLowerBound = TEST_SUGGESTION_LOWER_BOUND.minusSeconds(1);
+        GnssTimeSuggestion timeSuggestion =
+                script.generateGnssTimeSuggestion(belowLowerBound);
+        script.simulateGnssTimeSuggestion(timeSuggestion)
+                .verifySystemClockWasNotSetAndResetCallTracking();
+    }
+
+    @Test
+    public void testSuggestGnssTime_notRejectedAboveLowerBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
+                        .setOriginPriorities(ORIGIN_GNSS)
+                        .setAutoSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant aboveLowerBound = TEST_SUGGESTION_LOWER_BOUND.plusSeconds(1);
+        GnssTimeSuggestion timeSuggestion =
+                script.generateGnssTimeSuggestion(aboveLowerBound);
+        script.simulateGnssTimeSuggestion(timeSuggestion)
+                .verifySystemClockWasSetAndResetCallTracking(aboveLowerBound.toEpochMilli());
+    }
+
+    @Test
+    public void testSuggestGnssTime_rejectedAboveUpperBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
+                        .setOriginPriorities(ORIGIN_GNSS)
+                        .setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant aboveUpperBound = TEST_SUGGESTION_UPPER_BOUND.plusSeconds(1);
+        GnssTimeSuggestion timeSuggestion =
+                script.generateGnssTimeSuggestion(aboveUpperBound);
+        script.simulateGnssTimeSuggestion(timeSuggestion)
+                .verifySystemClockWasNotSetAndResetCallTracking();
+    }
+
+    @Test
+    public void testSuggestGnssTime_notRejectedBelowUpperBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
+                        .setOriginPriorities(ORIGIN_GNSS)
+                        .setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant belowUpperBound = TEST_SUGGESTION_UPPER_BOUND.minusSeconds(1);
+        GnssTimeSuggestion timeSuggestion =
+                script.generateGnssTimeSuggestion(belowUpperBound);
+        script.simulateGnssTimeSuggestion(timeSuggestion)
+                .verifySystemClockWasSetAndResetCallTracking(belowUpperBound.toEpochMilli());
+    }
+
+    @Test
     public void testSuggestExternalTime_autoTimeEnabled() {
         ConfigurationInternal configInternal =
                 new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
@@ -680,20 +895,67 @@
     }
 
     @Test
-    public void externalTimeSuggestion_ignoredWhenReferencedTimeIsInThePast() {
+    public void testSuggestExternalTime_rejectedBelowLowerBound() {
         ConfigurationInternal configInternal =
                 new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
                         .setOriginPriorities(ORIGIN_EXTERNAL)
+                        .setAutoSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
                         .build();
         Script script = new Script().simulateConfigurationInternalChange(configInternal);
 
-        Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1));
+        Instant belowLowerBound = TEST_SUGGESTION_LOWER_BOUND.minusSeconds(1);
         ExternalTimeSuggestion timeSuggestion =
-                script.generateExternalTimeSuggestion(suggestedTime);
-
+                script.generateExternalTimeSuggestion(belowLowerBound);
         script.simulateExternalTimeSuggestion(timeSuggestion)
-                .verifySystemClockWasNotSetAndResetCallTracking()
-                .assertLatestExternalSuggestion(null);
+                .verifySystemClockWasNotSetAndResetCallTracking();
+    }
+
+    @Test
+    public void testSuggestExternalTime_notRejectedAboveLowerBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
+                        .setOriginPriorities(ORIGIN_EXTERNAL)
+                        .setAutoSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant aboveLowerBound = TEST_SUGGESTION_LOWER_BOUND.plusSeconds(1);
+        ExternalTimeSuggestion timeSuggestion =
+                script.generateExternalTimeSuggestion(aboveLowerBound);
+        script.simulateExternalTimeSuggestion(timeSuggestion)
+                .verifySystemClockWasSetAndResetCallTracking(aboveLowerBound.toEpochMilli());
+    }
+
+    @Test
+    public void testSuggestExternalTime_rejectedAboveUpperBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
+                        .setOriginPriorities(ORIGIN_EXTERNAL)
+                        .setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant aboveUpperBound = TEST_SUGGESTION_UPPER_BOUND.plusSeconds(1);
+        ExternalTimeSuggestion timeSuggestion =
+                script.generateExternalTimeSuggestion(aboveUpperBound);
+        script.simulateExternalTimeSuggestion(timeSuggestion)
+                .verifySystemClockWasNotSetAndResetCallTracking();
+    }
+
+    @Test
+    public void testSuggestExternalTime_notRejectedBelowUpperBound() {
+        ConfigurationInternal configInternal =
+                new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
+                        .setOriginPriorities(ORIGIN_EXTERNAL)
+                        .setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
+                        .build();
+        Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+        Instant belowUpperBound = TEST_SUGGESTION_UPPER_BOUND.minusSeconds(1);
+        ExternalTimeSuggestion timeSuggestion =
+                script.generateExternalTimeSuggestion(belowUpperBound);
+        script.simulateExternalTimeSuggestion(timeSuggestion)
+                .verifySystemClockWasSetAndResetCallTracking(belowUpperBound.toEpochMilli());
     }
 
     @Test
@@ -1200,56 +1462,6 @@
                 .verifySystemClockWasSetAndResetCallTracking(ARBITRARY_TEST_TIME.toEpochMilli());
     }
 
-    @Test
-    public void manualY2038SuggestionsAreRejectedOnAffectedDevices() {
-        ConfigurationInternal configInternal =
-                new ConfigurationInternal.Builder(CONFIG_AUTO_DISABLED)
-                        .setOriginPriorities(ORIGIN_TELEPHONY)
-                        .setDeviceHasY2038Issue(true)
-                        .build();
-        Script script = new Script().simulateConfigurationInternalChange(configInternal);
-
-        Instant y2038IssueTime = Instant.ofEpochMilli((1L + Integer.MAX_VALUE) * 1000L);
-        ManualTimeSuggestion timeSuggestion = script.generateManualTimeSuggestion(y2038IssueTime);
-        script.simulateManualTimeSuggestion(
-                ARBITRARY_USER_ID, timeSuggestion, false /* expectedResult */)
-                .verifySystemClockWasNotSetAndResetCallTracking();
-    }
-
-    @Test
-    public void telephonyY2038SuggestionsAreRejectedOnAffectedDevices() {
-        ConfigurationInternal configInternal =
-                new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
-                        .setOriginPriorities(ORIGIN_TELEPHONY)
-                        .setDeviceHasY2038Issue(true)
-                        .build();
-        Script script = new Script().simulateConfigurationInternalChange(configInternal);
-
-        final int slotIndex = 0;
-        Instant y2038IssueTime = Instant.ofEpochMilli((1L + Integer.MAX_VALUE) * 1000L);
-        TelephonyTimeSuggestion timeSuggestion =
-                script.generateTelephonyTimeSuggestion(slotIndex, y2038IssueTime);
-        script.simulateTelephonyTimeSuggestion(timeSuggestion)
-                .verifySystemClockWasNotSetAndResetCallTracking();
-    }
-
-    @Test
-    public void telephonyY2038SuggestionsAreNotRejectedOnUnaffectedDevices() {
-        ConfigurationInternal configInternal =
-                new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
-                        .setOriginPriorities(ORIGIN_TELEPHONY)
-                        .setDeviceHasY2038Issue(false)
-                        .build();
-        Script script = new Script().simulateConfigurationInternalChange(configInternal);
-
-        final int slotIndex = 0;
-        Instant y2038IssueTime = Instant.ofEpochMilli((1L + Integer.MAX_VALUE) * 1000L);
-        TelephonyTimeSuggestion timeSuggestion =
-                script.generateTelephonyTimeSuggestion(slotIndex, y2038IssueTime);
-        script.simulateTelephonyTimeSuggestion(timeSuggestion)
-                .verifySystemClockWasSetAndResetCallTracking(y2038IssueTime.toEpochMilli());
-    }
-
     /**
      * A fake implementation of {@link TimeDetectorStrategyImpl.Environment}. Besides tracking
      * changes and behaving like the real thing should, it also asserts preconditions.
@@ -1573,7 +1785,7 @@
                     new TimestampedValue<>(
                             mFakeEnvironment.peekElapsedRealtimeMillis(),
                             suggestedTime.toEpochMilli());
-            return new NetworkTimeSuggestion(unixEpochTime);
+            return new NetworkTimeSuggestion(unixEpochTime, 123);
         }
 
         /**
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/GeolocationTimeZoneSuggestionTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/GeolocationTimeZoneSuggestionTest.java
index 79f8b0e..0f667b3 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/GeolocationTimeZoneSuggestionTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/GeolocationTimeZoneSuggestionTest.java
@@ -16,8 +16,13 @@
 
 package com.android.server.timezonedetector;
 
+import static com.android.server.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+
+import android.os.ShellCommand;
 
 import org.junit.Test;
 
@@ -66,4 +71,40 @@
         assertNotEquals(certain1v1, certain3);
         assertNotEquals(certain3, certain1v1);
     }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_noZoneIdsArg() {
+        ShellCommand testShellCommand =
+                createShellCommandWithArgsAndOptions(Collections.emptyList());
+        GeolocationTimeZoneSuggestion.parseCommandLineArg(testShellCommand);
+    }
+
+    @Test
+    public void testParseCommandLineArg_zoneIdsUncertain() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--zone_ids UNCERTAIN");
+        assertNull(GeolocationTimeZoneSuggestion.parseCommandLineArg(testShellCommand)
+                .getZoneIds());
+    }
+
+    @Test
+    public void testParseCommandLineArg_zoneIdsEmpty() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions("--zone_ids EMPTY");
+        assertEquals(Collections.emptyList(),
+                GeolocationTimeZoneSuggestion.parseCommandLineArg(testShellCommand).getZoneIds());
+    }
+
+    @Test
+    public void testParseCommandLineArg_zoneIdsPresent() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--zone_ids Europe/London,Europe/Paris");
+        assertEquals(Arrays.asList("Europe/London", "Europe/Paris"),
+                GeolocationTimeZoneSuggestion.parseCommandLineArg(testShellCommand).getZoneIds());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_unknownArgument() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions("--bad_arg 0");
+        GeolocationTimeZoneSuggestion.parseCommandLineArg(testShellCommand);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/ShellCommandTestSupport.java b/services/tests/servicestests/src/com/android/server/timezonedetector/ShellCommandTestSupport.java
new file mode 100644
index 0000000..b96c82f
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/ShellCommandTestSupport.java
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+package com.android.server.timezonedetector;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.os.ShellCommand;
+
+import org.mockito.stubbing.Answer;
+
+import java.util.Arrays;
+import java.util.List;
+
+/** Utility methods related to {@link ShellCommand} objects used in several tests. */
+public final class ShellCommandTestSupport {
+    private ShellCommandTestSupport() {}
+
+    public static ShellCommand createShellCommandWithArgsAndOptions(String argsWithSpaces) {
+        return createShellCommandWithArgsAndOptions(Arrays.asList(argsWithSpaces.split(" ")));
+    }
+
+    public static ShellCommand createShellCommandWithArgsAndOptions(List<String> args) {
+        ShellCommand command = mock(ShellCommand.class);
+        class ArgProvider {
+            private int mCount;
+
+            String getNext() {
+                if (mCount >= args.size()) {
+                    return null;
+                }
+                return args.get(mCount++);
+            }
+
+            String getNextRequired() {
+                String next = getNext();
+                if (next == null) {
+                    throw new IllegalArgumentException("No next");
+                }
+                return next;
+            }
+        }
+        ArgProvider argProvider = new ArgProvider();
+        when(command.getNextArg()).thenAnswer(
+                (Answer<String>) invocation -> argProvider.getNext());
+        when(command.getNextOption()).thenAnswer(
+                (Answer<String>) invocation -> argProvider.getNext());
+        when(command.getNextArgRequired()).thenAnswer(
+                (Answer<String>) invocation -> argProvider.getNextRequired());
+        return command;
+    }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
index a7d18ee..1b42fd3 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
@@ -18,7 +18,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -26,7 +25,6 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.app.AlarmManager;
 import android.app.NotificationHistory;
 import android.app.NotificationHistory.HistoricalNotification;
 import android.content.Context;
@@ -60,8 +58,6 @@
     Handler mFileWriteHandler;
     @Mock
     Context mContext;
-    @Mock
-    AlarmManager mAlarmManager;
 
     NotificationHistoryDatabase mDataBase;
 
@@ -96,22 +92,16 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        when(mContext.getSystemService(AlarmManager.class)).thenReturn(mAlarmManager);
         when(mContext.getUser()).thenReturn(getContext().getUser());
         when(mContext.getPackageName()).thenReturn(getContext().getPackageName());
 
         mRootDir = new File(mContext.getFilesDir(), "NotificationHistoryDatabaseTest");
 
-        mDataBase = new NotificationHistoryDatabase(mContext, mFileWriteHandler, mRootDir);
+        mDataBase = new NotificationHistoryDatabase(mFileWriteHandler, mRootDir);
         mDataBase.init();
     }
 
     @Test
-    public void testDeletionReceiver() {
-        verify(mContext, times(1)).registerReceiver(any(), any(), anyInt());
-    }
-
-    @Test
     public void testPrune() throws Exception {
         GregorianCalendar cal = new GregorianCalendar();
         cal.setTimeInMillis(10);
@@ -144,8 +134,6 @@
         mDataBase.prune(retainDays, cal.getTimeInMillis());
 
         assertThat(mDataBase.mHistoryFiles).containsExactlyElementsIn(expectedFiles);
-
-        verify(mAlarmManager, times(6)).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
     }
 
     @Test
@@ -412,15 +400,14 @@
         when(file.getName()).thenReturn("5");
         when(af.getBaseFile()).thenReturn(file);
 
-        wbr.run(5, af);
+        wbr.run(af);
 
         assertThat(mDataBase.mHistoryFiles.size()).isEqualTo(1);
         assertThat(mDataBase.mBuffer).isNotEqualTo(nh);
-        verify(mAlarmManager, times(1)).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
     }
 
     @Test
-    public void testRemoveFilePathFromHistory_hasMatch() throws Exception {
+    public void testRemoveFilePathFromHistory_hasMatch() {
         for (int i = 0; i < 5; i++) {
             AtomicFile af = mock(AtomicFile.class);
             when(af.getBaseFile()).thenReturn(new File(mRootDir, "af" + i));
@@ -436,7 +423,7 @@
     }
 
     @Test
-    public void testRemoveFilePathFromHistory_noMatch() throws Exception {
+    public void testRemoveFilePathFromHistory_noMatch() {
         for (int i = 0; i < 5; i++) {
             AtomicFile af = mock(AtomicFile.class);
             when(af.getBaseFile()).thenReturn(new File(mRootDir, "af" + i));
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryJobServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryJobServiceTest.java
new file mode 100644
index 0000000..af10b9d
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryJobServiceTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.notification;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.TestCase.assertFalse;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.app.job.JobServiceEngine;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.rule.ServiceTestRule;
+
+import com.android.server.LocalServices;
+import com.android.server.UiServiceTestCase;
+
+import org.junit.Before;
+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 java.lang.reflect.Field;
+
+@RunWith(AndroidTestingRunner.class)
+public class NotificationHistoryJobServiceTest extends UiServiceTestCase {
+    private NotificationHistoryJobService mJobService;
+    private JobParameters mJobParams = new JobParameters(null,
+            NotificationHistoryJobService.BASE_JOB_ID, null, null, null,
+            0, false, false, null, null, null);
+
+    @Captor
+    ArgumentCaptor<JobInfo> mJobInfoCaptor;
+
+    @Mock
+    private JobScheduler mMockJobScheduler;
+
+    @Mock
+    private NotificationManagerInternal mMockNotificationManagerInternal;
+
+    @Rule
+    public final ServiceTestRule mServiceRule = new ServiceTestRule();
+
+    @Before
+    public void setUp() throws Exception {
+        mJobService = new NotificationHistoryJobService();
+
+        final Field field = JobService.class.getDeclaredField("mEngine");
+        field.setAccessible(true);
+        field.set(mJobService, mock(JobServiceEngine.class));
+        mContext.addMockSystemService(JobScheduler.class, mMockJobScheduler);
+
+        // add NotificationManagerInternal to LocalServices
+        LocalServices.removeServiceForTest(NotificationManagerInternal.class);
+        LocalServices.addService(NotificationManagerInternal.class,
+                mMockNotificationManagerInternal);
+    }
+
+    @Test
+    public void testScheduleJob() {
+        // if asked, the job doesn't currently exist yet
+        when(mMockJobScheduler.getPendingJob(anyInt())).thenReturn(null);
+
+        // attempt to schedule the job
+        NotificationHistoryJobService.scheduleJob(mContext);
+        verify(mMockJobScheduler, times(1)).schedule(mJobInfoCaptor.capture());
+
+        // verify various properties of the job that is passed in to the job scheduler
+        JobInfo jobInfo = mJobInfoCaptor.getValue();
+        assertEquals(NotificationHistoryJobService.BASE_JOB_ID, jobInfo.getId());
+        assertFalse(jobInfo.isPersisted());
+        assertTrue(jobInfo.isPeriodic());
+    }
+
+    @Test
+    public void testOnStartJob() {
+        assertTrue(mJobService.onStartJob(mJobParams));
+
+        verify(mMockNotificationManagerInternal, timeout(500).atLeastOnce()).cleanupHistoryFiles();
+    }
+}
\ No newline at end of file
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 830237a..44ca9f4 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -8369,7 +8369,7 @@
     public void testOnUnlockUser() {
         UserInfo ui = new UserInfo();
         ui.id = 10;
-        mService.onUserUnlocking(new TargetUser(ui));
+        mService.onUserUnlocked(new TargetUser(ui));
         waitForIdle();
 
         verify(mHistoryManager, timeout(MAX_POST_DELAY).times(1)).onUserUnlocked(ui.id);
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 8bead57..7817e81 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
@@ -20,6 +20,7 @@
 
 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;
 
@@ -39,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;
@@ -50,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;
 
@@ -60,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;
@@ -198,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(
@@ -219,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
@@ -592,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);
@@ -616,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()));
@@ -636,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/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..d6b807f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -47,8 +47,10 @@
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -1402,6 +1404,28 @@
         win.setHasSurface(false);
     }
 
+    @Test
+    public void testCalculateSystemGestureExclusion_unrestricted() throws Exception {
+        mWm.mConstants.mSystemGestureExcludedByPreQStickyImmersive = true;
+
+        final DisplayContent dc = createNewDisplay();
+        final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win");
+        win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
+        win.getAttrs().layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+        win.getAttrs().privateFlags |= PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION;
+        win.setSystemGestureExclusion(Collections.singletonList(dc.getBounds()));
+
+        performLayout(dc);
+
+        win.setHasSurface(true);
+
+        final Region expected = Region.obtain();
+        expected.set(dc.getBounds());
+        assertEquals(expected, calculateSystemGestureExclusion(dc));
+
+        win.setHasSurface(false);
+    }
+
     @UseTestDisplay(addWindows = { W_ABOVE_ACTIVITY, W_ACTIVITY})
     @Test
     public void testRequestResizeForEmptyFrames() {
@@ -2118,7 +2142,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
@@ -2184,6 +2207,52 @@
         assertNotEquals(curSnapshot, mDisplayContent.mImeScreenshot);
     }
 
+    @UseTestDisplay(addWindows = {W_INPUT_METHOD})
+    @Test
+    public void testRemoveImeScreenshot_whenTargetSurfaceWasInvisible() {
+        final Task rootTask = createTask(mDisplayContent);
+        final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
+        final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
+        final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "win");
+        win.onSurfaceShownChanged(true);
+        makeWindowVisible(win, mDisplayContent.mInputMethodWindow);
+        task.getDisplayContent().prepareAppTransition(TRANSIT_CLOSE);
+        doReturn(true).when(task).okToAnimate();
+        ArrayList<WindowContainer> sources = new ArrayList<>();
+        sources.add(activity);
+
+        mDisplayContent.setImeLayeringTarget(win);
+        mDisplayContent.setImeInputTarget(win);
+        mDisplayContent.getInsetsStateController().getImeSourceProvider().setImeShowing(true);
+        task.applyAnimation(null, TRANSIT_OLD_TASK_CLOSE, false /* enter */,
+                false /* isVoiceInteraction */, sources);
+        assertNotNull(mDisplayContent.mImeScreenshot);
+
+        win.onSurfaceShownChanged(false);
+        assertNull(mDisplayContent.mImeScreenshot);
+    }
+
+    @UseTestDisplay(addWindows = {W_INPUT_METHOD})
+    @Test
+    public void testRemoveImeScreenshot_whenWindowRemoveImmediately() {
+        final Task rootTask = createTask(mDisplayContent);
+        final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
+        final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
+        final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "win");
+        makeWindowVisible(mDisplayContent.mInputMethodWindow);
+
+        mDisplayContent.setImeLayeringTarget(win);
+        mDisplayContent.setImeInputTarget(win);
+        mDisplayContent.getInsetsStateController().getImeSourceProvider().setImeShowing(true);
+        mDisplayContent.showImeScreenshot();
+        assertNotNull(mDisplayContent.mImeScreenshot);
+
+        // Expect IME snapshot will be removed when the win is IME layering target and invoked
+        // removeImeSurfaceByTarget.
+        win.removeImmediately();
+        assertNull(mDisplayContent.mImeScreenshot);
+    }
+
     @Test
     public void testRotateBounds_keepSamePhysicalPosition() {
         final DisplayContent dc =
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 2b131e1..8f2e9b4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -45,7 +45,12 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.graphics.PixelFormat;
@@ -344,4 +349,24 @@
         final InsetsSource navBarSource = state.peekSource(ITYPE_NAVIGATION_BAR);
         assertEquals(attrs.height - 10, navBarSource.getFrame().height());
     }
+
+    @Test
+    public void testCanSystemBarsBeShownByUser() {
+        ((TestWindowManagerPolicy) mWm.mPolicy).mIsUserSetupComplete = true;
+        final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
+        final WindowState windowState = mock(WindowState.class);
+        final InsetsSourceProvider provider = mock(InsetsSourceProvider.class);
+        final InsetsControlTarget controlTarget = mock(InsetsControlTarget.class);
+        when(provider.getControlTarget()).thenReturn(controlTarget);
+        when(windowState.getControllableInsetProvider()).thenReturn(provider);
+        when(controlTarget.getRequestedVisibility(anyInt())).thenReturn(true);
+
+        displayPolicy.setCanSystemBarsBeShownByUser(false);
+        displayPolicy.requestTransientBars(windowState, true);
+        verify(controlTarget, never()).showInsets(anyInt(), anyBoolean());
+
+        displayPolicy.setCanSystemBarsBeShownByUser(true);
+        displayPolicy.requestTransientBars(windowState, true);
+        verify(controlTarget).showInsets(anyInt(), anyBoolean());
+    }
 }
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/StubTransaction.java b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
index d275818..31546e8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
+++ b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
@@ -30,6 +30,7 @@
 import android.view.Surface;
 import android.view.SurfaceControl;
 
+import java.util.HashSet;
 import java.util.concurrent.Executor;
 
 /**
@@ -37,8 +38,14 @@
  * testing to avoid calls to native code.
  */
 public class StubTransaction extends SurfaceControl.Transaction {
+
+    private HashSet<Runnable> mWindowInfosReportedListeners = new HashSet<>();
+
     @Override
     public void apply() {
+        for (Runnable listener : mWindowInfosReportedListeners) {
+            listener.run();
+        }
     }
 
     @Override
@@ -47,6 +54,7 @@
 
     @Override
     public void apply(boolean sync) {
+        apply();
     }
 
     @Override
@@ -235,11 +243,6 @@
     }
 
     @Override
-    public SurfaceControl.Transaction syncInputWindows() {
-        return this;
-    }
-
-    @Override
     public SurfaceControl.Transaction setColorSpaceAgnostic(SurfaceControl sc, boolean agnostic) {
         return this;
     }
@@ -299,4 +302,10 @@
             boolean isTrustedOverlay) {
         return this;
     }
+
+    @Override
+    public SurfaceControl.Transaction addWindowInfosReportedListener(@NonNull Runnable listener) {
+        mWindowInfosReportedListeners.add(listener);
+        return this;
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index e47bcc9..97f0918 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -18,6 +18,12 @@
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_CHILDREN;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -237,10 +243,10 @@
 
         mController.registerOrganizer(mIOrganizer);
         mController.onTaskFragmentError(mTaskFragment.getTaskFragmentOrganizer(),
-                mErrorToken, exception);
+                mErrorToken, null /* taskFragment */, -1 /* opType */, exception);
         mController.dispatchPendingEvents();
 
-        verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), eq(exception));
+        verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), eq(null), eq(-1), eq(exception));
     }
 
     @Test
@@ -604,7 +610,9 @@
         verify(mAtm.getActivityStartController(), never()).startActivityInTaskFragment(any(), any(),
                 any(), any(), anyInt(), anyInt(), any());
         verify(mAtm.mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
-                eq(mErrorToken), any(IllegalArgumentException.class));
+                eq(mErrorToken), eq(mTaskFragment),
+                eq(HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT),
+                any(IllegalArgumentException.class));
     }
 
     @Test
@@ -619,7 +627,9 @@
         mWindowOrganizerController.applyTransaction(mTransaction);
 
         verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
-                eq(mErrorToken), any(IllegalArgumentException.class));
+                eq(mErrorToken), eq(mTaskFragment),
+                eq(HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT),
+                any(IllegalArgumentException.class));
         assertNull(activity.getOrganizedTaskFragment());
     }
 
@@ -635,7 +645,9 @@
         mWindowOrganizerController.applyTransaction(mTransaction);
 
         verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
-                eq(mErrorToken), any(IllegalArgumentException.class));
+                eq(mErrorToken), eq(mTaskFragment),
+                eq(HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS),
+                any(IllegalArgumentException.class));
         verify(mTaskFragment, never()).setAdjacentTaskFragment(any());
     }
 
@@ -654,7 +666,8 @@
         mWindowOrganizerController.applyTransaction(mTransaction);
 
         verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
-                eq(mErrorToken), any(IllegalArgumentException.class));
+                eq(mErrorToken), eq(null), eq(HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT),
+                any(IllegalArgumentException.class));
         assertNull(mWindowOrganizerController.getTaskFragment(fragmentToken));
     }
 
@@ -669,7 +682,8 @@
         mWindowOrganizerController.applyTransaction(mTransaction);
 
         verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
-                eq(mErrorToken), any(IllegalArgumentException.class));
+                eq(mErrorToken), eq(mTaskFragment), eq(HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT),
+                any(IllegalArgumentException.class));
         assertNotNull(mWindowOrganizerController.getTaskFragment(mFragmentToken));
 
         // Allow organizer to delete empty TaskFragment for cleanup.
@@ -931,7 +945,9 @@
         // The pending event will be dispatched on the handler (from requestTraversal).
         waitHandlerIdle(mWm.mAnimationHandler);
 
-        verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), any(SecurityException.class));
+        verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), any(),
+                eq(HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT),
+                any(SecurityException.class));
     }
 
     @Test
@@ -968,7 +984,8 @@
         // The pending event will be dispatched on the handler (from requestTraversal).
         waitHandlerIdle(mWm.mAnimationHandler);
 
-        verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), any(SecurityException.class));
+        verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), any(),
+                eq(HIERARCHY_OP_TYPE_REPARENT_CHILDREN), any(SecurityException.class));
     }
 
     @Test
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..f4323db 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
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 92457c7..851be9d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -40,6 +40,7 @@
 
     boolean mKeyguardShowingAndNotOccluded = false;
     boolean mOkToAnimate = true;
+    boolean mIsUserSetupComplete = false;
 
     TestWindowManagerPolicy() {
     }
@@ -284,7 +285,7 @@
 
     @Override
     public boolean isUserSetupComplete() {
-        return false;
+        return mIsUserSetupComplete;
     }
 
     @Override
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/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index 1715a29..c8ea70c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -22,8 +22,8 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static android.view.InsetsState.ITYPE_LOCAL_NAVIGATION_BAR_1;
-import static android.view.InsetsState.ITYPE_LOCAL_NAVIGATION_BAR_2;
+import static android.view.InsetsState.ITYPE_BOTTOM_GENERIC_OVERLAY;
+import static android.view.InsetsState.ITYPE_TOP_GENERIC_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.TRANSIT_CLOSE;
@@ -1302,40 +1302,42 @@
                 TYPE_BASE_APPLICATION);
         attrs2.setTitle("AppWindow2");
         activity2.addWindow(createWindowState(attrs2, activity2));
-        Rect navigationBarInsetsRect1 = new Rect(0, 200, 1080, 700);
-        Rect navigationBarInsetsRect2 = new Rect(0, 0, 1080, 200);
+        Rect genericOverlayInsetsRect1 = new Rect(0, 200, 1080, 700);
+        Rect genericOverlayInsetsRect2 = new Rect(0, 0, 1080, 200);
 
-        rootTask.addLocalRectInsetsSourceProvider(navigationBarInsetsRect1,
-                new int[]{ITYPE_LOCAL_NAVIGATION_BAR_1});
-        container.addLocalRectInsetsSourceProvider(navigationBarInsetsRect2,
-                new int[]{ITYPE_LOCAL_NAVIGATION_BAR_2});
+        rootTask.addLocalRectInsetsSourceProvider(genericOverlayInsetsRect1,
+                new int[]{ITYPE_TOP_GENERIC_OVERLAY});
+        container.addLocalRectInsetsSourceProvider(genericOverlayInsetsRect2,
+                new int[]{ITYPE_BOTTOM_GENERIC_OVERLAY});
 
-        InsetsSource navigationBarInsetsProvider1Source = new InsetsSource(
-                ITYPE_LOCAL_NAVIGATION_BAR_1);
-        navigationBarInsetsProvider1Source.setFrame(navigationBarInsetsRect1);
-        navigationBarInsetsProvider1Source.setVisible(true);
-        InsetsSource navigationBarInsetsProvider2Source = new InsetsSource(
-                ITYPE_LOCAL_NAVIGATION_BAR_2);
-        navigationBarInsetsProvider2Source.setFrame(navigationBarInsetsRect2);
-        navigationBarInsetsProvider2Source.setVisible(true);
+        InsetsSource genericOverlayInsetsProvider1Source = new InsetsSource(
+                ITYPE_TOP_GENERIC_OVERLAY);
+        genericOverlayInsetsProvider1Source.setFrame(genericOverlayInsetsRect1);
+        genericOverlayInsetsProvider1Source.setVisible(true);
+        InsetsSource genericOverlayInsetsProvider2Source = new InsetsSource(
+                ITYPE_BOTTOM_GENERIC_OVERLAY);
+        genericOverlayInsetsProvider2Source.setFrame(genericOverlayInsetsRect2);
+        genericOverlayInsetsProvider2Source.setVisible(true);
 
         activity0.forAllWindows(window -> {
-            assertEquals(navigationBarInsetsRect1,
-                    window.getInsetsState().peekSource(ITYPE_LOCAL_NAVIGATION_BAR_1).getFrame());
+            assertEquals(genericOverlayInsetsRect1,
+                    window.getInsetsState().peekSource(ITYPE_TOP_GENERIC_OVERLAY).getFrame());
             assertEquals(null,
-                    window.getInsetsState().peekSource(ITYPE_LOCAL_NAVIGATION_BAR_2));
+                    window.getInsetsState().peekSource(ITYPE_BOTTOM_GENERIC_OVERLAY));
         }, true);
         activity1.forAllWindows(window -> {
-            assertEquals(navigationBarInsetsRect1,
-                    window.getInsetsState().peekSource(ITYPE_LOCAL_NAVIGATION_BAR_1).getFrame());
-            assertEquals(navigationBarInsetsRect2,
-                    window.getInsetsState().peekSource(ITYPE_LOCAL_NAVIGATION_BAR_2).getFrame());
+            assertEquals(genericOverlayInsetsRect1,
+                    window.getInsetsState().peekSource(ITYPE_TOP_GENERIC_OVERLAY).getFrame());
+            assertEquals(genericOverlayInsetsRect2,
+                    window.getInsetsState().peekSource(ITYPE_BOTTOM_GENERIC_OVERLAY)
+                            .getFrame());
         }, true);
         activity2.forAllWindows(window -> {
-            assertEquals(navigationBarInsetsRect1,
-                    window.getInsetsState().peekSource(ITYPE_LOCAL_NAVIGATION_BAR_1).getFrame());
-            assertEquals(navigationBarInsetsRect2,
-                    window.getInsetsState().peekSource(ITYPE_LOCAL_NAVIGATION_BAR_2).getFrame());
+            assertEquals(genericOverlayInsetsRect1,
+                    window.getInsetsState().peekSource(ITYPE_TOP_GENERIC_OVERLAY).getFrame());
+            assertEquals(genericOverlayInsetsRect2,
+                    window.getInsetsState().peekSource(ITYPE_BOTTOM_GENERIC_OVERLAY)
+                            .getFrame());
         }, true);
     }
 
@@ -1344,7 +1346,7 @@
          /*
                 ___ rootTask ________________________________________
                |                  |                                  |
-          activity0      navigationBarInsetsProvider1    navigationBarInsetsProvider2
+          activity0      genericOverlayInsetsProvider1    genericOverlayInsetsProvider2
          */
         final Task rootTask = createTask(mDisplayContent);
 
@@ -1355,22 +1357,22 @@
         attrs.setTitle("AppWindow0");
         activity0.addWindow(createWindowState(attrs, activity0));
 
-        Rect navigationBarInsetsRect1 = new Rect(0, 200, 1080, 700);
-        Rect navigationBarInsetsRect2 = new Rect(0, 0, 1080, 200);
+        Rect genericOverlayInsetsRect1 = new Rect(0, 200, 1080, 700);
+        Rect genericOverlayInsetsRect2 = new Rect(0, 0, 1080, 200);
 
-        rootTask.addLocalRectInsetsSourceProvider(navigationBarInsetsRect1,
-                new int[]{ITYPE_LOCAL_NAVIGATION_BAR_1});
+        rootTask.addLocalRectInsetsSourceProvider(genericOverlayInsetsRect1,
+                new int[]{ITYPE_TOP_GENERIC_OVERLAY});
         activity0.forAllWindows(window -> {
-            assertEquals(navigationBarInsetsRect1,
-                    window.getInsetsState().peekSource(ITYPE_LOCAL_NAVIGATION_BAR_1).getFrame());
+            assertEquals(genericOverlayInsetsRect1,
+                    window.getInsetsState().peekSource(ITYPE_TOP_GENERIC_OVERLAY).getFrame());
         }, true);
 
-        rootTask.addLocalRectInsetsSourceProvider(navigationBarInsetsRect2,
-                new int[]{ITYPE_LOCAL_NAVIGATION_BAR_1});
+        rootTask.addLocalRectInsetsSourceProvider(genericOverlayInsetsRect2,
+                new int[]{ITYPE_TOP_GENERIC_OVERLAY});
 
         activity0.forAllWindows(window -> {
-            assertEquals(navigationBarInsetsRect2,
-                    window.getInsetsState().peekSource(ITYPE_LOCAL_NAVIGATION_BAR_1).getFrame());
+            assertEquals(genericOverlayInsetsRect2,
+                    window.getInsetsState().peekSource(ITYPE_TOP_GENERIC_OVERLAY).getFrame());
         }, true);
     }
 
@@ -1412,30 +1414,32 @@
         Rect navigationBarInsetsRect2 = new Rect(0, 0, 1080, 200);
 
         rootTask.addLocalRectInsetsSourceProvider(navigationBarInsetsRect1,
-                new int[]{ITYPE_LOCAL_NAVIGATION_BAR_1});
+                new int[]{ITYPE_TOP_GENERIC_OVERLAY});
         container.addLocalRectInsetsSourceProvider(navigationBarInsetsRect2,
-                new int[]{ITYPE_LOCAL_NAVIGATION_BAR_2});
+                new int[]{ITYPE_BOTTOM_GENERIC_OVERLAY});
         mDisplayContent.getInsetsStateController().onPostLayout();
-        rootTask.removeLocalInsetsSourceProvider(new int[]{ITYPE_LOCAL_NAVIGATION_BAR_1});
+        rootTask.removeLocalInsetsSourceProvider(new int[]{ITYPE_TOP_GENERIC_OVERLAY});
         mDisplayContent.getInsetsStateController().onPostLayout();
 
         activity0.forAllWindows(window -> {
             assertEquals(null,
-                    window.getInsetsState().peekSource(ITYPE_LOCAL_NAVIGATION_BAR_1));
+                    window.getInsetsState().peekSource(ITYPE_TOP_GENERIC_OVERLAY));
             assertEquals(null,
-                    window.getInsetsState().peekSource(ITYPE_LOCAL_NAVIGATION_BAR_2));
+                    window.getInsetsState().peekSource(ITYPE_BOTTOM_GENERIC_OVERLAY));
         }, true);
         activity1.forAllWindows(window -> {
             assertEquals(null,
-                    window.getInsetsState().peekSource(ITYPE_LOCAL_NAVIGATION_BAR_1));
+                    window.getInsetsState().peekSource(ITYPE_TOP_GENERIC_OVERLAY));
             assertEquals(navigationBarInsetsRect2,
-                    window.getInsetsState().peekSource(ITYPE_LOCAL_NAVIGATION_BAR_2).getFrame());
+                    window.getInsetsState().peekSource(ITYPE_BOTTOM_GENERIC_OVERLAY)
+                                    .getFrame());
         }, true);
         activity2.forAllWindows(window -> {
             assertEquals(null,
-                    window.getInsetsState().peekSource(ITYPE_LOCAL_NAVIGATION_BAR_1));
+                    window.getInsetsState().peekSource(ITYPE_TOP_GENERIC_OVERLAY));
             assertEquals(navigationBarInsetsRect2,
-                    window.getInsetsState().peekSource(ITYPE_LOCAL_NAVIGATION_BAR_2).getFrame());
+                    window.getInsetsState().peekSource(ITYPE_BOTTOM_GENERIC_OVERLAY)
+                            .getFrame());
         }, true);
     }
 
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..84c2c55 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -30,7 +30,7 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
 import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
-import static android.view.InsetsState.ITYPE_LOCAL_NAVIGATION_BAR_1;
+import static android.view.InsetsState.ITYPE_TOP_GENERIC_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
@@ -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)
@@ -762,11 +779,11 @@
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         wct.addRectInsetsProvider(navigationBarInsetsReceiverTask.mRemoteToken
                         .toWindowContainerToken(), navigationBarInsetsProviderRect,
-                new int[]{ITYPE_LOCAL_NAVIGATION_BAR_1});
+                new int[]{ITYPE_TOP_GENERIC_OVERLAY});
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
 
         assertThat(navigationBarInsetsReceiverTask.mLocalInsetsSourceProviders
-                .valueAt(0).getSource().getType()).isEqualTo(ITYPE_LOCAL_NAVIGATION_BAR_1);
+                .valueAt(0).getSource().getType()).isEqualTo(ITYPE_TOP_GENERIC_OVERLAY);
     }
 
     @Test
@@ -782,12 +799,12 @@
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         wct.addRectInsetsProvider(navigationBarInsetsReceiverTask.mRemoteToken
                         .toWindowContainerToken(), navigationBarInsetsProviderRect,
-                new int[]{ITYPE_LOCAL_NAVIGATION_BAR_1});
+                new int[]{ITYPE_TOP_GENERIC_OVERLAY});
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
 
         final WindowContainerTransaction wct2 = new WindowContainerTransaction();
         wct2.removeInsetsProvider(navigationBarInsetsReceiverTask.mRemoteToken
-                .toWindowContainerToken(), new int[]{ITYPE_LOCAL_NAVIGATION_BAR_1});
+                .toWindowContainerToken(), new int[]{ITYPE_TOP_GENERIC_OVERLAY});
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct2);
 
         assertThat(navigationBarInsetsReceiverTask.mLocalInsetsSourceProviders.size()).isEqualTo(0);
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 446ec8b..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})
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/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/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/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/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index ecdb194..1f97d86 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -3121,8 +3121,9 @@
      * @param callback Callback will be triggered once it succeeds or failed.
      *                 Pass null if don't care about the result.
      *
+     * @throws IllegalStateException when subscription manager service is not available.
+     * @throws SecurityException when clients do not have MODIFY_PHONE_STATE permission.
      * @hide
-     *
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@@ -3132,7 +3133,9 @@
         if (VDBG) logd("[setPreferredDataSubscriptionId]+ subId:" + subId);
         try {
             ISub iSub = TelephonyManager.getSubscriptionService();
-            if (iSub == null) return;
+            if (iSub == null) {
+                throw new IllegalStateException("subscription manager service is null.");
+            }
 
             ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() {
                 @Override
@@ -3152,7 +3155,8 @@
             };
             iSub.setPreferredDataSubscriptionId(subId, needValidation, callbackStub);
         } catch (RemoteException ex) {
-            // ignore it
+            loge("setPreferredDataSubscriptionId RemoteException=" + ex);
+            ex.rethrowFromSystemServer();
         }
     }
 
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 24374ee..a7468a9 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -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
@@ -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.
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/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 2e97eb1..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,25 +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
+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)
     }
 }
 
@@ -75,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()) {
@@ -218,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
@@ -228,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 730e5bc..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)
         }
     }
 
@@ -192,7 +86,7 @@
     @Test
     open fun launcherLayerReplacesApp() {
         testSpec.replacesLayer(
-            testApp.component,
+            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..149576e 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)
+            .withAppTransitionIdle()
             .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..6ceb9ea 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,56 @@
 @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 taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
+    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 +99,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 +113,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 +137,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..452aa63 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,95 +44,56 @@
 @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()
-    }
-
-    @FlakyTest(bugId = 206753786)
-    @Test
-    fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    @Presubmit
-    @Test
-    fun visibleLayersShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertLayers {
-            this.visibleLayersShownMoreThanOneConsecutiveEntry()
-        }
+    fun navBarLayerPositionAtStartAndEndLandscapeOrSeascapeAtStart() {
+        Assume.assumeFalse(testSpec.isTablet)
+        Assume.assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
+        testSpec.navBarLayerPositionAtStartAndEnd()
     }
 
     @Presubmit
@@ -151,7 +104,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..4569a5b 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,72 @@
 @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 taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
     /**
-     * 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..977719c 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,11 @@
 
 package com.android.server.wm.flicker.ime
 
-import android.app.Instrumentation
 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 +28,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 +67,65 @@
 @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()
         }
     }
 
     /**
-     * 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..b10aed3 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,18 @@
 
 package com.android.server.wm.flicker.ime
 
-import android.app.Instrumentation
 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,88 +45,50 @@
 @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
     @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @Presubmit
-    @Test
     fun imeWindowBecomesInvisible() = testSpec.imeWindowBecomesInvisible()
 
     @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..e85b9c0 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,47 @@
 @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()
 
     @Presubmit
     @Test
@@ -102,19 +94,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 +113,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..16cf22a 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,32 +94,25 @@
      */
     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
     @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @Presubmit
-    @Test
     fun imeWindowIsAlwaysVisible() {
         testSpec.imeWindowIsAlwaysVisible()
     }
 
     @Presubmit
     @Test
-    fun navBarLayerIsVisible3Button() {
-        assumeFalse(testSpec.isGesturalNavigation)
-        testSpec.navBarLayerIsVisible()
+    fun navBarLayerIsVisibleAtStartAndEnd3Button() {
+        Assume.assumeFalse(testSpec.isTablet)
+        Assume.assumeFalse(testSpec.isGesturalNavigation)
+        testSpec.navBarLayerIsVisibleAtStartAndEnd()
     }
 
     /**
@@ -137,63 +120,133 @@
      */
     @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()
     }
 
     /**
      * 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
      */
-    @Postsubmit
+    @Presubmit
     @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()
+
+    @Presubmit
+    @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 +264,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..4954adb 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,22 @@
 
 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 +47,61 @@
 @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)
             }
         }
     }
 
+    /** {@inheritDoc} */
     @Presubmit
     @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
+    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 statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @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 +124,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)
+    @Presubmit
     @Test
-    fun imeAppWindowVisibility() {
-        assumeTrue(isShellTransitionsEnabled)
+    fun imeAppWindowIsAlwaysVisibleShellTransit() {
+        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)
+    @Presubmit
     @Test
-    fun imeLayerIsBecomesVisible() {
-        assumeTrue(isShellTransitionsEnabled)
+    fun imeLayerBecomesVisibleShellTransit() {
+        Assume.assumeTrue(isShellTransitionsEnabled)
         testSpec.assertLayers {
-            this.isVisible(FlickerComponentName.IME)
+            this.isVisible(ComponentMatcher.IME)
         }
     }
 
@@ -203,33 +178,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 027a04f..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(
-                        testApp.component
-                            .or(FlickerComponentName.SNAPSHOT)
-                            .or(FlickerComponentName.SPLASH_SCREEN)
-                    )
+            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 fcf7c1d..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
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 46f378e..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
@@ -180,6 +192,12 @@
     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 f7ec940..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,79 +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()
-
-    /** {@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/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 eaf4dac..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,10 +61,81 @@
             }
         }
 
+    /** {@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()
@@ -84,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 9e9b0c9..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,74 +127,43 @@
             }
         }
 
-    @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
-    @Postsubmit
-    fun notificationAppWindowVisibleAtEnd() {
-        testSpec.assertWmEnd {
-            this.isAppWindowVisible(testApp.component)
-        }
-    }
-
-    @Test
-    @Postsubmit
-    fun notificationAppWindowOnTopAtEnd() {
-        testSpec.assertWmEnd {
-            this.isAppWindowOnTop(testApp.component)
-        }
-    }
-
-    @Test
-    @Postsubmit
-    fun notificationAppLayerVisibleAtEnd() {
-        testSpec.assertLayersEnd {
-            this.isVisible(testApp.component)
-        }
-    }
-
     /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun appWindowBecomesTopWindow() {
-        Assume.assumeFalse(isShellTransitionsEnabled)
-        super.appWindowBecomesTopWindow()
-    }
-
-    @FlakyTest(bugId = 229738092)
-    @Test
-    fun appWindowBecomesTopWindow_ShellTransit() {
-        Assume.assumeTrue(isShellTransitionsEnabled)
-        super.appWindowBecomesTopWindow()
-    }
-
-    /** {@inheritDoc} */
-    @Postsubmit
-    @Test
-    override fun statusBarWindowIsVisible() = super.statusBarWindowIsVisible()
+    override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
 
     /** {@inheritDoc} */
     @Postsubmit
@@ -196,12 +173,12 @@
     /** {@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
@@ -215,6 +192,45 @@
     override fun appWindowIsTopWindowAtEnd() =
         super.appWindowIsTopWindowAtEnd()
 
+    @Postsubmit
+    @Test
+    open fun notificationAppWindowVisibleAtEnd() {
+        testSpec.assertWmEnd {
+            this.isAppWindowVisible(testApp)
+        }
+    }
+
+    @Postsubmit
+    @Test
+    open fun notificationAppWindowOnTopAtEnd() {
+        testSpec.assertWmEnd {
+            this.isAppWindowOnTop(testApp)
+        }
+    }
+
+    @Postsubmit
+    @Test
+    open fun notificationAppLayerVisibleAtEnd() {
+        testSpec.assertLayersEnd {
+            this.isVisible(testApp)
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun appWindowBecomesTopWindow() {
+        Assume.assumeFalse(isShellTransitionsEnabled)
+        super.appWindowBecomesTopWindow()
+    }
+
+    @FlakyTest(bugId = 229738092)
+    @Test
+    open fun appWindowBecomesTopWindow_ShellTransit() {
+        Assume.assumeTrue(isShellTransitionsEnabled)
+        super.appWindowBecomesTopWindow()
+    }
+
     companion object {
         /**
          * Creates the test configurations.
@@ -226,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 ec083509..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()
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..b482e5f 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()
+                .withAppTransitionIdle()
+                .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..386c0cb 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,22 @@
      */
     @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()
-
-    /**
-     * Checks that the navbar layer is visible throughout the entire transition.
-     */
-    @Presubmit
-    @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 taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
 
     companion object {
         private var startDisplayBounds = Rect.EMPTY
@@ -318,13 +276,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..cefcb35 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,32 @@
     @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} */
+    @FlakyTest(bugId = 239148258)
     @Test
-    open fun navbarIsAlwaysInRightPosition() {
-        testSpec.navBarLayerRotatesAndScales()
-    }
-
-    /**
-     * Checks that the status bar window is visible throughout the entire transition.
-     */
-    @Presubmit
-    @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/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
index 7b17778..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;
@@ -203,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");
diff --git a/tests/UpdatableSystemFontTest/Android.bp b/tests/UpdatableSystemFontTest/Android.bp
index 9a9e42b..9bfcc18 100644
--- a/tests/UpdatableSystemFontTest/Android.bp
+++ b/tests/UpdatableSystemFontTest/Android.bp
@@ -37,6 +37,7 @@
         "vts",
     ],
     data: [
+        ":EmojiRenderingTestApp",
         ":UpdatableSystemFontTestCertDer",
         ":UpdatableSystemFontTest_NotoColorEmoji.ttf",
         ":UpdatableSystemFontTest_NotoColorEmoji.sig",
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..2601041 100644
--- a/tools/lint/Android.bp
+++ b/tools/lint/Android.bp
@@ -29,10 +29,17 @@
         "auto_service_annotations",
         "lint_api",
     ],
+    kotlincflags: ["-Xjvm-default=all"],
 }
 
 java_test_host {
     name: "AndroidFrameworkLintCheckerTest",
+    // TODO(b/239881504): Since this test was written, Android
+    // Lint was updated, and now includes classes that were
+    // compiled for java 15. The soong build doesn't support
+    // java 15 yet, so we can't compile against "lint". Disable
+    // the test until java 15 is supported.
+    enabled: false,
     srcs: ["checks/src/test/java/**/*.kt"],
     static_libs: [
         "AndroidFrameworkLintChecker",